package com.ktgj.flight.common.linkstar;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.google.common.base.Strings;
import com.ktgj.common.core.constant.FlightOrderChangeConstants;
import com.ktgj.common.core.constant.FlightOrderConstants;
import com.ktgj.common.core.domain.R;
import com.ktgj.common.core.enums.EnumHelper;
import com.ktgj.common.core.utils.DateCalcUtils;
import com.ktgj.common.core.utils.DateUtils;
import com.ktgj.common.core.utils.SnowflakeUtils;
import com.ktgj.common.core.utils.helper.StringHelper;
import com.ktgj.common.core.utils.xml.XElement;
import com.ktgj.customer.api.RemoteCustomerService;
import com.ktgj.customer.api.domain.Customer;
import com.ktgj.flight.common.BaseClass;
import com.ktgj.flight.common.huaxia.domain.RefundRule;
import com.ktgj.flight.common.linkstar.domain.CabinRefundChangeRules;
import com.ktgj.flight.common.linkstar.domain.CalculateRefundRes;
import com.ktgj.flight.common.linkstar.domain.TicketInfoResponse;
import com.ktgj.flight.common.linkstar.domain.airReIssuePrice.AirReIssuePriceRequest;
import com.ktgj.flight.common.linkstar.domain.airReIssuePrice.ReIssuePriceResponse;
import com.ktgj.flight.common.linkstar.domain.baseclass.Airline;
import com.ktgj.flight.common.linkstar.domain.baseclass.ArrivalAirport;
import com.ktgj.flight.common.linkstar.domain.baseclass.POS;
import com.ktgj.flight.common.linkstar.domain.baseclass.Source;
import com.ktgj.flight.common.linkstar.domain.calculation.CalculationResponse;
import com.ktgj.flight.common.linkstar.domain.changeFlight.ChangeFlightRequest;
import com.ktgj.flight.common.linkstar.domain.changesearch.*;
import com.ktgj.flight.common.linkstar.domain.fightdetails.FlightInfoReqVo;
import com.ktgj.flight.common.linkstar.domain.fightdetails.FlightInfoVo;
import com.ktgj.flight.common.linkstar.domain.fightdetails.request.AirDetail;
import com.ktgj.flight.common.linkstar.domain.fightdetails.request.DepartureAirport;
import com.ktgj.flight.common.linkstar.domain.fightdetails.request.OTA_AirDetailsRQ;
import com.ktgj.flight.common.linkstar.domain.fightdetails.response.OTA_AirDetailsRS;
import com.ktgj.flight.common.linkstar.domain.publishprice.FlightPublishPriceReqVo;
import com.ktgj.flight.common.linkstar.domain.publishprice.FlightPublishPriceResVo;
import com.ktgj.flight.common.linkstar.domain.publishprice.OTA_AirFareDisplayRSRes;
import com.ktgj.flight.common.linkstar.domain.searchFlight.one.*;
import com.ktgj.flight.common.linkstar.domain.searchFlight.round.*;
import com.ktgj.flight.common.linkstar.domain.stopfight.FightStopReqVo;
import com.ktgj.flight.common.linkstar.domain.stopfight.FightStopResVo;
import com.ktgj.flight.common.linkstar.domain.stopfight.FlightLegBrief;
import com.ktgj.flight.common.linkstar.util.HttpHelper;
import com.ktgj.flight.common.pay._HuiFu;
import com.ktgj.flight.common.pay._Yeepay;
import com.ktgj.flight.common.qunar._Qunar;
import com.ktgj.flight.domain.*;
import com.ktgj.flight.domain.InterfaceEntity.*;
import com.ktgj.flight.service.*;
import com.ktgj.flight.service.impl.TicketProducter;
import org.apache.commons.lang.BooleanUtils;
import org.json.JSONObject;
import org.json.XML;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author wyj
 * @create 2021-10-28 11:19
 */
@Service
public class LinkStar extends BaseClass {

    @Autowired
    private IAirportService airportService;

    @Autowired
    private IFlightAdjustService flightAdjustService; //大客户信息

    @Autowired
    private IFlightOrderInfoService orderInfoService; //订单主表

    @Autowired
    private IFlightOrderInfoTicketsService orderInfoTicketsService; //订单从表

    @Autowired
    private IFlightInterfaceService interfaceService; //渠道从表

    @Autowired
    private IFlightChannelRuleService channelRuleService; //渠道主表

    @Autowired
    private IFlightOrderChangeService flightOrderChangeService; //退票申请表

    @Autowired
    private _HuiFu huifu;

    @Autowired
    private _Yeepay yeePay;

    @Autowired
    private TicketProducter ticketProducter;

    @Autowired
    private IFlightAdjustService adjustService;

    @Autowired
    private RemoteCustomerService customerService;

    @Autowired
    private IFlightOutticketLogService outticketLogService;

    @Autowired
    private IFlightOrderChangeTicketsService changeTicketsService;

    @Autowired
    private IFlightOrderExceptionService flightOrderExceptionService;


    //测试环境
    //测试地址
    // private static String URL = "https://linkstar.travelsky.com.cn/develop/xml";
    private static String URL = "http://172.16.2.65:9527/ota/xml";
    //用户名
    private static final String USER_NAME = "jssj";
    //密码
    //private static final String USER_PWD = "IkmV15rGJqkg";
    //office
    private static final String OFFICE = "PEK602";

    //iatacode号
    private static final String IATACODE = "08321961";


    //正式环境密码
    private static final String USER_PWD = "pDTaKR9X92fH";
    private final Logger logger = LoggerFactory.getLogger(LinkStar.class);

//    领达改签流程
//    1、首选变更航班搜索   （changeSearchFlight） 搜索出来的是相同航司，不同日期的航班号
//    2、航班预订 （_OrderCreate），在搜索出来的航班中选择需要改签的航班 预订即可（跟正常预订没有区别，但是需要预订后的pnr，在后边计算改签费用时需要使用,改签成功后这个pnr需要更新到数据库（以后用户需要退票时，使用的是这个新pnr））
//    3、计算改签费用 （airReIssuePrice） 传入改签的航班信息，新生成的pnr、之前的票号，计算出当前改签需要支付的差价
//    4、申请改签（ticketChangesFlight） 需要改签的航班信息，新生成的pnr，原来的票号，改签成功后会生成新的票号（将新出的票号和新的pnr做关联，退票时使用新的pnr才可以）
    // pnr 为领达记录编，相当于订单号
    // 领达PNR预定，必须先走运价计算，如果没有运价，无法预定
    // 领达舱位验价 走的是 C1 运价计算

    /**
     * 机票查询
     *
     * @param moRequest
     * @return
     */
    @Override
    public MoFlightSearchResponse _FlightSearch(MoFlightSearchRequest moRequest) {

        if (moRequest.GoSearchWhere.OrgAirport.equals("PEK"))
            moRequest.GoSearchWhere.OrgAirport = "BJS";
        if (moRequest.GoSearchWhere.DstAirport.equals("PEK"))
            moRequest.GoSearchWhere.DstAirport = "BJS";
        if (moRequest.BackSearchWhere.OrgAirport != null && moRequest.BackSearchWhere.OrgAirport.equals("PEK"))
            moRequest.BackSearchWhere.OrgAirport = "BJS";
        if (moRequest.BackSearchWhere.DstAirport != null && moRequest.BackSearchWhere.DstAirport.equals("PEK"))
            moRequest.BackSearchWhere.DstAirport = "BJS";

        MoFlightSearchResponse response = new MoFlightSearchResponse();

        String strRequestData = "";
        String strResponseData = "";
        try {

            if (moRequest.TripType == EnumHelper.TripType.单程.getValue()) {
                if (Strings.isNullOrEmpty(moRequest.GoSearchWhere.DepDate)) {
                    response.ErrorMsg = "出发日期不能不为空";
                    return response;
                }
            } else if (moRequest.TripType == EnumHelper.TripType.往返.getValue()) {
                if (Strings.isNullOrEmpty(moRequest.GoSearchWhere.DepDate)) {
                    response.ErrorMsg = "出发日期不能不为空";
                    return response;
                }
                if (Strings.isNullOrEmpty(moRequest.BackSearchWhere.DepDate)) {
                    response.ErrorMsg = "往返日期不能不为空";
                    return response;
                }
            }

            strRequestData += String.format("<FareInterface>\n" +
                    "    <Input>\n" +
                    "        <HeaderIn>\n" +
                    "            <sysCode>CRS</sysCode>\n" +
                    "            <channelID>1E</channelID>\n" +
                    "            <Agency>\n" +
                    "                <officeId>%s</officeId>\n" +
                    "                <pid>11996</pid>\n" +
                    "                <city>BJS</city>\n" +
                    "            </Agency>\n" +
                    "            <language>CN</language>\n" +
                    "            <commandType>FS</commandType>\n" +
                    "        </HeaderIn>\n" +
                    "        <Request>\n" +
                    "            <FlightShopRequest>", OFFICE);


            //单程信息查询
            if (moRequest.TripType == EnumHelper.TripType.单程.getValue()) {

                String date = splicingData(moRequest.GoSearchWhere.DepDate);

                if (moRequest.hasChildrenBaby) {
                    strRequestData += String.format("\n" +
                            "                <OriginDestinationInfo>\n" +
                            "                    <ori>%s</ori>\n" +
                            "                    <des>%s</des>\n" +
                            "                    <DepartureDate>%s</DepartureDate>\n" +
                            "                </OriginDestinationInfo>\n" +
                            "                <TravelPreferences>\n" +
                            "                    <displayCurrCode>CNY</displayCurrCode>\n" +
                            "                    <currCode>CNY</currCode>\n" +
                            "                    <isDirectFlightOnly>false</isDirectFlightOnly>\n" +
                            "                    <journeyType>OW</journeyType>\n" +
                            "                    <isDealModel>false</isDealModel>\n" +
                            "                    <passenger>\n" +
                            "                        <number>1</number>\n" +
                            "                        <type>AD</type>\n" +
                            "                    </passenger>\n" +
                            "                    <passenger>\n" +
                            "                        <number>1</number>\n" +
                            "                        <type>CH</type>\n" +
                            "                    </passenger>\n" +
                            "                    <passenger>\n" +
                            "                        <number>1</number>\n" +
                            "                        <type>IN</type>\n" +
                            "                    </passenger>\n" +
                            "                </TravelPreferences>\n", moRequest.GoSearchWhere.OrgAirport, moRequest.GoSearchWhere.DstAirport, date);
                } else {
                    if (moRequest.hasChildren) {
                        strRequestData += String.format("\n" +
                                "                <OriginDestinationInfo>\n" +
                                "                    <ori>%s</ori>\n" +
                                "                    <des>%s</des>\n" +
                                "                    <DepartureDate>%s</DepartureDate>\n" +
                                "                </OriginDestinationInfo>\n" +
                                "                <TravelPreferences>\n" +
                                "                    <displayCurrCode>CNY</displayCurrCode>\n" +
                                "                    <currCode>CNY</currCode>\n" +
                                "                    <isDirectFlightOnly>false</isDirectFlightOnly>\n" +
                                "                    <journeyType>OW</journeyType>\n" +
                                "                    <isDealModel>false</isDealModel>\n" +
                                "                    <passenger>\n" +
                                "                        <number>1</number>\n" +
                                "                        <type>AD</type>\n" +
                                "                    </passenger>\n" +
                                "                    <passenger>\n" +
                                "                        <number>1</number>\n" +
                                "                        <type>CH</type>\n" +
                                "                    </passenger>\n" +
                                "                </TravelPreferences>\n", moRequest.GoSearchWhere.OrgAirport, moRequest.GoSearchWhere.DstAirport, date);
                    } else {
                        strRequestData += String.format("\n" +
                                "                <OriginDestinationInfo>\n" +
                                "                    <ori>%s</ori>\n" +
                                "                    <des>%s</des>\n" +
                                "                    <DepartureDate>%s</DepartureDate>\n" +
                                "                </OriginDestinationInfo>\n" +
                                "                <TravelPreferences>\n" +
                                "                    <displayCurrCode>CNY</displayCurrCode>\n" +
                                "                    <currCode>CNY</currCode>\n" +
                                "                    <isDirectFlightOnly>false</isDirectFlightOnly>\n" +
                                "                    <journeyType>OW</journeyType>\n" +
                                "                    <isDealModel>false</isDealModel>\n" +
                                "                    <passenger>\n" +
                                "                        <number>1</number>\n" +
                                "                        <type>AD</type>\n" +
                                "                    </passenger>\n" +
                                "                </TravelPreferences>\n", moRequest.GoSearchWhere.OrgAirport, moRequest.GoSearchWhere.DstAirport, date);
                    }
                }


                //大客户
                if (moRequest.hasKeyCustomers) {
                    strRequestData += String.format("\n" +
                            "                <SpecificCarrierInfo>\n" +
                            "                    <carrier>%s</carrier>\n" +
                            "                    <accountCode>%s</accountCode>\n" +
                            "                </SpecificCarrierInfo>\n", moRequest.carrier, moRequest.accountCode);
                }

            }
            //往返查询
            else {
                String goDate = splicingData(moRequest.GoSearchWhere.DepDate);
                String backDate = splicingData(moRequest.BackSearchWhere.DepDate);

                //TODO 往返因接口不支持，暂时屏蔽儿童、婴儿价格查询，暂由成人票价格来计算儿童票价格
                strRequestData += String.format("<OriginDestinationInfo>\n" +
                                "                    <ori>%s</ori>\n" +
                                "                    <des>%s</des>\n" +
                                "                    <DepartureDate>%s</DepartureDate>\n" +
                                "                </OriginDestinationInfo>\n" +
                                "                <OriginDestinationInfo>\n" +
                                "                    <ori>%s</ori>\n" +
                                "                    <des>%s</des>\n" +
                                "                    <DepartureDate>%s</DepartureDate>\n" +
                                "                </OriginDestinationInfo>\n" +
                                "                <TravelPreferences>\n" +
                                "                    <cabinClass />\n" +
                                "                    <displayCurrCode>CNY</displayCurrCode>\n" +
                                "                    <currCode>CNY</currCode>\n" +
                                "                    <isDirectFlightOnly>true</isDirectFlightOnly>\n" +
                                "                    <journeyType>RT</journeyType>\n" +
                                "                    <isDealModel>false</isDealModel>\n" +
                                "                    <passenger>\n" +
                                "                        <number>1</number>\n" +
                                "                        <type>AD</type>\n" +
                                "                    </passenger>\n" +
                                "                </TravelPreferences>\n", moRequest.GoSearchWhere.OrgAirport, moRequest.GoSearchWhere.DstAirport, goDate,
                        moRequest.BackSearchWhere.OrgAirport, moRequest.BackSearchWhere.DstAirport, backDate);
            }

            strRequestData += String.format("\n" +
                    "                <Option>\n" +
                    "                    <fcFeature>0</fcFeature>\n" +
                    "                    <isAvNeeded>Y</isAvNeeded>\n" +
                    "                    <isPSnNeeded>Y</isPSnNeeded>\n" +
                    "                    <isPsAvBindsNeeded>N</isPsAvBindsNeeded>\n" +
                    "                    <isFaresNeeded>Y</isFaresNeeded>\n" +
                    "                    <ruleTypeNeeded>NON</ruleTypeNeeded>\n" +
                    "                    <format>SIM</format>\n" +
                    "                    <isCabinFareNeeded>Y</isCabinFareNeeded>\n" +
                    "                    <lowestOrAll>A</lowestOrAll>\n" +
                    "                    <fareSource>ALL</fareSource>\n" +
                    "                    <isRefundReissueRuleNeeded>Y</isRefundReissueRuleNeeded>\n" +
                    "                </Option>\n" +
                    "           </FlightShopRequest>\n" +
                    "        </Request>\n" +
                    "    </Input>\n" +
                    "</FareInterface>");


            //发送请求
            strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirFlightShop/D", strRequestData);
            SearchFlightRes flightRes = new SearchFlightRes();
            XElement root = XElement.loadXml(strResponseData);
            if (root.toString().contains("Error")) {
                //错误处理
                XElement ResultEnt = root.element("Output").element("Result").element("Error");
                JSONObject message = XML.toJSONObject(ResultEnt.element("message").toString());
                JSONObject code = XML.toJSONObject(ResultEnt.element("code").toString());
                response.ErrorMsg = JSON.parseObject(message.toString(), String.class);
                response.ErrorCode = JSON.parseObject(code.toString(), String.class);
                return response;
            }
            XmlMapper xmlMapper = new XmlMapper();
            FareInterface fareInterface = new FareInterface();
            Output Output = new Output();
            SResult Result = new SResult();
            FlightShopResult FlightShopResult = new FlightShopResult();

            XElement elementPsn = root.element("Output").element("Result").element("FlightShopResult").element("PSn");
            JSONObject elementPsnXml = XML.toJSONObject(elementPsn.toString());
            String psnJson = elementPsnXml.toString();
            FlightShopResult flightShopResult = JSON.parseObject(psnJson, FlightShopResult.class);
            PSn psnResult = flightShopResult.PSn;
            FlightShopResult.PSn = psnResult;

            XElement elementPFares = root.element("Output").element("Result").element("FlightShopResult").element("PFares");
            JSONObject elementPFaresXml = XML.toJSONObject(elementPFares.toString());
            String pFaresJson = elementPFaresXml.toString();
            FlightShopResult flightShopResultPf = JSON.parseObject(pFaresJson, FlightShopResult.class);
            PFares pFares = flightShopResultPf.PFares;
            FlightShopResult.PFares = pFares;

            XElement elementNFares = root.element("Output").element("Result").element("FlightShopResult").element("NFares");
            JSONObject elementNFaresXml = XML.toJSONObject(elementNFares.toString());
            String nFaresJson = elementNFaresXml.toString();
            FlightShopResult flightShopResultNf = JSON.parseObject(nFaresJson, FlightShopResult.class);
            NFares nFares = flightShopResultNf.NFares;
            FlightShopResult.NFares = nFares;

            XElement refElement = root.element("Output").element("Result").element("FlightShopResult").element("FsRefundRuleDisplay");
            JSONObject refundXml = XML.toJSONObject(refElement.toString());
            String refundJson = refundXml.toString();
            FlightShopResult ruleDisplay = JSON.parseObject(refundJson, FlightShopResult.class);
            FlightShopResult.FsRefundRuleDisplay = ruleDisplay.FsRefundRuleDisplay;

            XElement chaElement = root.element("Output").element("Result").element("FlightShopResult").element("FsReissueRuleDisplay");
            JSONObject changeXml = XML.toJSONObject(chaElement.toString());
            String changeJson = changeXml.toString();
            FlightShopResult reissueRuleDisplay = JSON.parseObject(changeJson, FlightShopResult.class);
            FlightShopResult.FsReissueRuleDisplay = reissueRuleDisplay.FsReissueRuleDisplay;

            List<XElement> lstAvOpt = root.element("Output").element("Result").element("FlightShopResult").element("AvJourneys").element("AvJourney").elements("AvOpt");
            for (XElement AvOpt : lstAvOpt) {
                AvOpt opt = new AvOpt();
                if (AvOpt.elements("Flt").size() == 2) {
                    for (XElement fltTwo : AvOpt.elements("Flt")) {
                        Flt flt = xmlMapper.readValue(fltTwo.toString(), Flt.class);
                        opt.Flt.add(flt);
                    }
                    FlightShopResult.AvJourneys.AvJourney.AvOpt.add(opt);
                } else {
                    Flt flt = xmlMapper.readValue(AvOpt.element("Flt").toString(), Flt.class);
                    opt.Flt.add(flt);
                    FlightShopResult.AvJourneys.AvJourney.AvOpt.add(opt);
                }
            }
            Result.FlightShopResult = FlightShopResult;
            Output.Result = Result;
            fareInterface.Output = Output;
            flightRes.FareInterface = fareInterface;

            //将xml转为json
            JSONObject xml = XML.toJSONObject(strResponseData);
            String jsonStr = xml.toString(4);

            //解析单程
            if (moRequest.TripType == EnumHelper.TripType.单程.getValue()) {

                //响应错误
                if (flightRes.FareInterface.Output.Result.Error != null) {
                    response.ErrorCode = flightRes.FareInterface.Output.Result.Error.code;
                    response.ErrorMsg = flightRes.FareInterface.Output.Result.Error.message;
                    return response;
                }


                //航班仓位价格
                List<PS> ps = flightRes.FareInterface.Output.Result.FlightShopResult.PSn.PS;
                //舱位等级
                List<PFare> pFare = null;
                List<NFare> nFare = null;
                if (flightRes.FareInterface.Output.Result.FlightShopResult.PFares != null)
                    pFare = flightRes.FareInterface.Output.Result.FlightShopResult.PFares.PFare;
                if (flightRes.FareInterface.Output.Result.FlightShopResult.NFares != null)
                    nFare = flightRes.FareInterface.Output.Result.FlightShopResult.NFares.NFare;
                //退票规则
                List<FSRefundDetailDisplay> refund = flightRes.FareInterface.Output.Result.FlightShopResult.FsRefundRuleDisplay.FSRefundDetailDisplay;
                //改签规则
                List<FSReissueDetailDisplay> change = flightRes.FareInterface.Output.Result.FlightShopResult.FsReissueRuleDisplay.FSReissueDetailDisplay;
                //航班信息
                List<AvOpt> avOptList = flightRes.FareInterface.Output.Result.FlightShopResult.AvJourneys.AvJourney.AvOpt;
                for (int i = 0; i < avOptList.size(); i++) {
                    if (avOptList.get(i).Flt.size() > 1) { //解析带有中转的航班数据
                        for (Flt flt : avOptList.get(i).Flt) {
                            //共享航班
                            /*if (flt.codeshare != null) {
                                *//*info.IsCodeShare = true;
                                info.Carrier = flt.codeshare.airline + flt.codeshare.fltno;*//*
                                continue;
                            }*/
                            MoFlightInfo info = new MoFlightInfo();
                            info.Airline = flt.airline; //航司
                            String fltNo = flt.fltNo; //航班号
                            info.FlightNo = fltNo;
                            String DstAirport = flt.arr;
                            info.DstAirport = DstAirport;
                            //抵达机场名称
                            info.DstAirportName = getAirPortNameByRirPortCode(DstAirport);
                            String OrgAirport = flt.dep;
                            info.OrgAirport = OrgAirport;
                            //出发机场名称
                            info.OrgAirportName = getAirPortNameByRirPortCode(OrgAirport);
                            info.TPM = Integer.parseInt(flt.tpm);
                            info.StopCount = flt.stop;
                            info.PlaneStyle = flt.dev; //机型
                            info.depad = flt.depad;
                            info.arrad = flt.arrad;
                            //航站楼
                            if (flt.term != null) {
                                Term term = flt.term;
                                info.ArrTerm = term.arr;
                                info.DepTerm = term.dep;
                            }
                            String deptm = flt.deptm;
                            String deptmDate = moRequest.GoSearchWhere.DepDate + " " + insertStr(deptm, 2, ":");
                            if (flt.depad == 0) {
                                info.DepDate = convertStrToDate(deptmDate);
                            } else {
                                Date date = convertStrToDate(deptmDate);
                                info.DepDate = DateCalcUtils.addDay(date, flt.depad);
                            }

                            String arrtm = flt.arrtm;
                            String arrtmDate = moRequest.GoSearchWhere.DepDate + " " + insertStr(arrtm, 2, ":");
                            if (flt.arrad == 0) {
                                info.ArrDate = convertStrToDate(arrtmDate);
                            } else {
                                Date date = convertStrToDate(arrtmDate);
                                info.ArrDate = DateCalcUtils.addDay(date, flt.arrad);
                            }

                            //计算飞行时长
                            long diff = info.DepDate.getTime() - info.ArrDate.getTime();
                            long diffMinutes = diff / (60 * 1000) % 60;
                            long diffHours = diff / (60 * 60 * 1000) % 24;

                            String flightTimes = "";
                            if (diffHours == 0) {
                                flightTimes = diffMinutes + "分钟";
                            } else if (diffMinutes == 0) {
                                flightTimes = diffHours + "小时";
                            } else if (diffHours != 0 && diffMinutes != 0) {
                                flightTimes = diffHours + "小时" + diffMinutes + "分钟";
                            }

                            info.flightTimes = flightTimes.replace("-", "");
                            //获取返回的仓位信息
                            String classStr = flt.classStr;
                            String[] cabins = classStr.split(";");
                            for (String cabin : cabins) {
                                //仓位
                                MoCabinInfo cinfo = new MoCabinInfo();
                                //餐食
                                String meal = flt.meal;
                                if (!StringHelper.isNullOrEmpty(meal)) {
                                    String mealSub = meal.substring(0, 1);
                                    String mealSubTwo = meal.substring(1);
                                    if (mealSubTwo != null && !mealSubTwo.equals("")) {
                                        cinfo.Meal = meal(mealSubTwo);
                                    } else {
                                        cinfo.Meal = meal(mealSub);
                                    }
                                }else {
                                    cinfo.Meal = "无";
                                }
                                String[] split = cabin.split(":");
                                cinfo.Cabin = split[0];
                                if ("A".equals(split[1])) {
                                    cinfo.CabinLeftDesc = "座位充足";
                                } else {
                                    cinfo.CabinLeftDesc = String.valueOf(Integer.parseInt(split[1]));
                                }

                                String flight = flt.airline + flt.fltNo + ":" + cinfo.Cabin;
                                //仓位价格处理
                                Set<String> refundSet = new HashSet<>();
                                Set<String> chRefundSet = new HashSet<>();
                                Set<String> inRefundSet = new HashSet<>();
                                Set<String> changeSet = new HashSet<>();
                                Set<String> chChangeSet = new HashSet<>();
                                Set<String> inChangeSet = new HashSet<>();
                                for (PS item : ps)
                                {
                                    String[] routStr = {};
                                    for (Routs routs : item.Routs)
                                    {
                                        routStr = routs.routStr.split("\\|");
                                    }
                                    List<FC> fc = item.FCs.FC;
                                    //燃油和基建
                                    String[] cnTax = getTaxInfo(item.Taxes.Tax.get(0).taxComponent);
                                    String[] yqTax = getTaxInfo(item.Taxes.Tax.get(1).taxComponent);
                                    if (routStr.length > 1)
                                    {

                                        if (routStr[0].equals(flight))
                                        {
                                            if (item.passengerType.equals("AD")) {
                                                info.AirportTax = new BigDecimal(cnTax[0]);
                                                info.FuelTax = new BigDecimal(yqTax[0]);
                                            } else if (item.passengerType.equals("CH")) {
                                                info.ChildAirportTax = new BigDecimal(cnTax[0]);
                                                info.ChildFuelTax = new BigDecimal(yqTax[0]);
                                            } else if (item.passengerType.equals("IN")) {
                                                info.InfantAirportTax = new BigDecimal(cnTax[0]);
                                                info.InfantFuelTax = new BigDecimal(yqTax[0]);
                                            }
                                            String disAmt = fc.get(0).disAmt;
                                            if (item.passengerType.equals("AD")) {
                                                cinfo.CallCenterAmountInfo.OrgTicketAmount = new BigDecimal(disAmt);
                                            } else if (item.passengerType.equals("CH")) {
                                                cinfo.CallCenterAmountInfo.OrgChdTicketAmount = new BigDecimal(disAmt);
                                            } else if (item.passengerType.equals("IN")) {
                                                cinfo.CallCenterAmountInfo.OrgIftTicketAmount = new BigDecimal(disAmt);
                                            }
                                            if (item.FCs.FC.size()==2)
                                            {
                                                cinfo.CallCenterAmountInfo.TicketAmount = new BigDecimal(item.FCs.FC.get(0).YFares.yFareAmount);
                                            }else
                                            {
                                                String[] arrFc = getTaxInfo(item.FCs.FC.get(0).YFares.yFareAmount);
                                                cinfo.CallCenterAmountInfo.TicketAmount = new BigDecimal(arrFc[0]);
                                            }
                                            String cabinLevelId = item.FCs.FC.get(0).FareBind.fareRPH;
                                            getCabinLevel(cabinLevelId, cinfo, pFare, nFare);

                                            List<String> refundRph = null;
                                            List<String> changeRph = null;
                                            if (item.FCs.FC.size() > 1) {
                                                if (item.FCs.FC.get(1).RefundDetailRph != null && item.FCs.FC.get(1).ReissueDetailRph != null) {
                                                    refundRph = item.FCs.FC.get(1).RefundDetailRph;
                                                    changeRph = item.FCs.FC.get(1).ReissueDetailRph;
                                                } else {
                                                    refundRph = item.FCs.FC.get(0).RefundDetailRph;
                                                    changeRph = item.FCs.FC.get(0).ReissueDetailRph;
                                                }
                                                if (item.FCs.FC.get(1).SecInfo.size() > 1) {
                                                    if (item.passengerType.equals("AD")) {
                                                        if (item.FCs.FC.get(1).SecInfo.get(1).Baggage != null)
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(1).Baggage;
                                                        else if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                        else if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null) {
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                        } else if (item.FCs.FC.get(0).SecInfo.get(0).Baggage != null) {
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                        }
                                                    } else if (item.passengerType.equals("CH")) {
                                                        if (item.FCs.FC.get(1).SecInfo.get(1).Baggage != null)
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(1).Baggage;
                                                        else if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                        else if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null) {
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                        } else if (item.FCs.FC.get(0).SecInfo.get(0).Baggage != null) {
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                        }
                                                    }
                                                } else {
                                                    if (item.passengerType.equals("AD")) {
                                                        if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                        else
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    } else if (item.passengerType.equals("CH")) {
                                                        if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                        else
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    }
                                                }
                                            } else {
                                                refundRph = item.FCs.FC.get(0).RefundDetailRph;
                                                changeRph = item.FCs.FC.get(0).ReissueDetailRph;
                                                if (item.passengerType.equals("AD")) {
                                                    if (item.FCs.FC.get(0).SecInfo.size() > 1) {
                                                        if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null)
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                        else
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    } else {
                                                        cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    }
                                                } else if (item.passengerType.equals("CH")) {
                                                    if (item.FCs.FC.get(0).SecInfo.size() > 1) {
                                                        if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null)
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                        else
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    } else {
                                                        cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    }
                                                }
                                            }

                                            if (cinfo.CabinRule.refundRph.size() == 0) {
                                                if (item.passengerType.equals("AD")) {
                                                    if (refundRph.size() > 0) {
                                                        if (refundSet.add(info.FlightNo + cinfo.Cabin + refundRph))
                                                            cinfo.CabinRule.refundRph.addAll(refundRph);
                                                    }
                                                } else if (item.passengerType.equals("CH")) {
                                                    if (refundRph.size() > 0) {
                                                        if (chRefundSet.add(info.FlightNo + cinfo.Cabin + refundRph))
                                                            cinfo.ChdCabinRule.refundRph.addAll(refundRph);
                                                    }
                                                } else if (item.passengerType.equals("IN")) {
                                                    if (refundRph.size() > 0) {
                                                        if (inRefundSet.add(info.FlightNo + cinfo.Cabin + refundRph))
                                                            cinfo.IftCabinRule.refundRph.addAll(refundRph);
                                                    }
                                                }
                                            }
                                            if (cinfo.CabinRule.changeRph.size() == 0) {
                                                if (item.passengerType.equals("AD")) {
                                                    if (changeRph.size() > 0) {
                                                        if (changeSet.add(info.FlightNo + cinfo.Cabin + changeRph))
                                                            cinfo.CabinRule.changeRph.addAll(changeRph);
                                                    }
                                                } else if (item.passengerType.equals("CH")) {
                                                    if (changeRph.size() > 0) {
                                                        if (chChangeSet.add(info.FlightNo + cinfo.Cabin + changeRph))
                                                            cinfo.ChdCabinRule.changeRph.addAll(changeRph);
                                                    }
                                                } else if (item.passengerType.equals("IN")) {
                                                    if (changeRph.size() > 0) {
                                                        if (inChangeSet.add(info.FlightNo + cinfo.Cabin + changeRph))
                                                            cinfo.IftCabinRule.changeRph.addAll(changeRph);
                                                    }
                                                }
                                            }
                                            info.ListCabinInfo.add(cinfo);
                                            break;
                                        }
                                        if (routStr[1].equals(flight))
                                        {
                                            if (item.passengerType.equals("AD")) {
                                                info.AirportTax = new BigDecimal(cnTax[1]);
                                                info.FuelTax = new BigDecimal(yqTax[1]);
                                            } else if (item.passengerType.equals("CH")) {
                                                info.ChildAirportTax = new BigDecimal(cnTax[1]);
                                                info.ChildFuelTax = new BigDecimal(yqTax[1]);
                                            } else if (item.passengerType.equals("IN")) {
                                                info.InfantAirportTax = new BigDecimal(cnTax[1]);
                                                info.InfantFuelTax = new BigDecimal(yqTax[1]);
                                            }
                                            if (item.FCs.FC.size()==2)
                                            {
                                                String disAmt = fc.get(1).disAmt;
                                                if (item.passengerType.equals("AD")) {
                                                    cinfo.CallCenterAmountInfo.OrgTicketAmount = new BigDecimal(disAmt);
                                                } else if (item.passengerType.equals("CH")) {
                                                    cinfo.CallCenterAmountInfo.OrgChdTicketAmount = new BigDecimal(disAmt);
                                                } else if (item.passengerType.equals("IN")) {
                                                    cinfo.CallCenterAmountInfo.OrgIftTicketAmount = new BigDecimal(disAmt);
                                                }
                                                cinfo.CallCenterAmountInfo.TicketAmount = new BigDecimal(item.FCs.FC.get(1).YFares.yFareAmount);
                                                String cabinLevelId = item.FCs.FC.get(1).FareBind.fareRPH;
                                                getCabinLevel(cabinLevelId, cinfo, pFare, nFare);
                                            }else
                                            {
                                                String disAmt = fc.get(0).disAmt;
                                                if (item.passengerType.equals("AD")) {
                                                    cinfo.CallCenterAmountInfo.OrgTicketAmount = new BigDecimal(disAmt);
                                                } else if (item.passengerType.equals("CH")) {
                                                    cinfo.CallCenterAmountInfo.OrgChdTicketAmount = new BigDecimal(disAmt);
                                                } else if (item.passengerType.equals("IN")) {
                                                    cinfo.CallCenterAmountInfo.OrgIftTicketAmount = new BigDecimal(disAmt);
                                                }
                                                String[] arrFc = getTaxInfo(item.FCs.FC.get(0).YFares.yFareAmount);
                                                cinfo.CallCenterAmountInfo.TicketAmount = new BigDecimal(arrFc[1]);
                                                String cabinLevelId = item.FCs.FC.get(0).FareBind.fareRPH;
                                                getCabinLevel(cabinLevelId, cinfo, pFare, nFare);
                                            }

                                            List<String> refundRph = null;
                                            List<String> changeRph = null;
                                            if (item.FCs.FC.size() > 1) {
                                                if (item.FCs.FC.get(1).RefundDetailRph != null && item.FCs.FC.get(1).ReissueDetailRph != null) {
                                                    refundRph = item.FCs.FC.get(1).RefundDetailRph;
                                                    changeRph = item.FCs.FC.get(1).ReissueDetailRph;
                                                } else {
                                                    refundRph = item.FCs.FC.get(0).RefundDetailRph;
                                                    changeRph = item.FCs.FC.get(0).ReissueDetailRph;
                                                }
                                                if (item.FCs.FC.get(1).SecInfo.size() > 1) {
                                                    if (item.passengerType.equals("AD")) {
                                                        if (item.FCs.FC.get(1).SecInfo.get(1).Baggage != null)
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(1).Baggage;
                                                        else if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                        else if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null) {
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                        } else if (item.FCs.FC.get(0).SecInfo.get(0).Baggage != null) {
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                        }
                                                    } else if (item.passengerType.equals("CH")) {
                                                        if (item.FCs.FC.get(1).SecInfo.get(1).Baggage != null)
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(1).Baggage;
                                                        else if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                        else if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null) {
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                        } else if (item.FCs.FC.get(0).SecInfo.get(0).Baggage != null) {
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                        }
                                                    }
                                                } else {
                                                    if (item.passengerType.equals("AD")) {
                                                        if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                        else
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    } else if (item.passengerType.equals("CH")) {
                                                        if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                        else
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    }
                                                }
                                            } else {
                                                refundRph = item.FCs.FC.get(0).RefundDetailRph;
                                                changeRph = item.FCs.FC.get(0).ReissueDetailRph;
                                                if (item.passengerType.equals("AD")) {
                                                    if (item.FCs.FC.get(0).SecInfo.size() > 1) {
                                                        if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null)
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                        else
                                                            cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    } else {
                                                        cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    }
                                                } else if (item.passengerType.equals("CH")) {
                                                    if (item.FCs.FC.get(0).SecInfo.size() > 1) {
                                                        if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null)
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                        else
                                                            cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    } else {
                                                        cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    }
                                                }
                                            }

                                            if (cinfo.CabinRule.refundRph.size() == 0) {
                                                if (item.passengerType.equals("AD")) {
                                                    if (refundRph.size() > 0) {
                                                        if (refundSet.add(info.FlightNo + cinfo.Cabin + refundRph))
                                                            cinfo.CabinRule.refundRph.addAll(refundRph);
                                                    }
                                                } else if (item.passengerType.equals("CH")) {
                                                    if (refundRph.size() > 0) {
                                                        if (chRefundSet.add(info.FlightNo + cinfo.Cabin + refundRph))
                                                            cinfo.ChdCabinRule.refundRph.addAll(refundRph);
                                                    }
                                                } else if (item.passengerType.equals("IN")) {
                                                    if (refundRph.size() > 0) {
                                                        if (inRefundSet.add(info.FlightNo + cinfo.Cabin + refundRph))
                                                            cinfo.IftCabinRule.refundRph.addAll(refundRph);
                                                    }
                                                }
                                            }
                                            if (cinfo.CabinRule.changeRph.size() == 0) {
                                                if (item.passengerType.equals("AD")) {
                                                    if (changeRph.size() > 0) {
                                                        if (changeSet.add(info.FlightNo + cinfo.Cabin + changeRph))
                                                            cinfo.CabinRule.changeRph.addAll(changeRph);
                                                    }
                                                } else if (item.passengerType.equals("CH")) {
                                                    if (changeRph.size() > 0) {
                                                        if (chChangeSet.add(info.FlightNo + cinfo.Cabin + changeRph))
                                                            cinfo.ChdCabinRule.changeRph.addAll(changeRph);
                                                    }
                                                } else if (item.passengerType.equals("IN")) {
                                                    if (changeRph.size() > 0) {
                                                        if (inChangeSet.add(info.FlightNo + cinfo.Cabin + changeRph))
                                                            cinfo.IftCabinRule.changeRph.addAll(changeRph);
                                                    }
                                                }
                                            }
                                            info.ListCabinInfo.add(cinfo);
                                            break;
                                        }
                                    }
                                }
                            }
                            response.transferFlightInfo.add(info);
                        }
                    } else { //直飞
                        Flt flt = avOptList.get(i).Flt.get(0);
                        //共享航班
                        if (flt.codeshare != null) {
                            /*info.IsCodeShare = true;
                            info.Carrier = flt.codeshare.airline + flt.codeshare.fltno;*/
                            continue;
                        }
                        MoFlightInfo info = new MoFlightInfo();
                        info.Airline = flt.airline; //航司
                        if (flt.stopOvers != null) {
                            info.stopPlace = flt.stopOvers.stopInfo.stopCity;
                            info.stopTime = flt.stopOvers.stopInfo.stopTime;
                        }
                        String fltNo = flt.fltNo; //航班号
                        info.FlightNo = fltNo;
                        String DstAirport = flt.arr;
                        info.DstAirport = DstAirport;
                        //抵达机场名称
                        info.DstAirportName = getAirPortNameByRirPortCode(DstAirport);
                        String OrgAirport = flt.dep;
                        info.OrgAirport = OrgAirport;
                        //出发机场名称
                        info.OrgAirportName = getAirPortNameByRirPortCode(OrgAirport);
                        info.TPM = Integer.parseInt(flt.tpm);
                        info.StopCount = flt.stop;
                        info.PlaneStyle = flt.dev; //机型

                        info.depad = flt.depad;
                        info.arrad = flt.arrad;

                        String deptm = flt.deptm;
                        String deptmDate = moRequest.GoSearchWhere.DepDate + " " + insertStr(deptm, 2, ":");
                        if (flt.depad == 0) {
                            info.DepDate = convertStrToDate(deptmDate);
                        } else {
                            Date date = convertStrToDate(deptmDate);
                            info.DepDate = DateCalcUtils.addDay(date, flt.depad);
                        }

                        String arrtm = flt.arrtm;
                        String arrtmDate = moRequest.GoSearchWhere.DepDate + " " + insertStr(arrtm, 2, ":");
                        if (flt.arrad == 0) {
                            info.ArrDate = convertStrToDate(arrtmDate);
                        } else {
                            Date date = convertStrToDate(arrtmDate);
                            info.ArrDate = DateCalcUtils.addDay(date, flt.arrad);
                        }

                        //计算飞行时长
                        long diff = info.DepDate.getTime() - info.ArrDate.getTime();
                        long diffMinutes = diff / (60 * 1000) % 60;
                        long diffHours = diff / (60 * 60 * 1000) % 24;

                        String flightTimes = "";
                        if (diffHours == 0) {
                            flightTimes = diffMinutes + "分钟";
                        } else if (diffMinutes == 0) {
                            flightTimes = diffHours + "小时";
                        } else if (diffHours != 0 && diffMinutes != 0) {
                            flightTimes = diffHours + "小时" + diffMinutes + "分钟";
                        }

                        info.flightTimes = flightTimes.replace("-", "");

                        //航站楼
                        Term term = flt.term;
                        if (term != null) {
                            info.ArrTerm = term.arr;
                            info.DepTerm = term.dep;
                        }

                        //获取返回的仓位信息
                        String classStr = flt.classStr;
                        String[] cabins = classStr.split(";");
                        Set<String> refundSet = new HashSet<>();
                        Set<String> chRefundSet = new HashSet<>();
                        Set<String> inRefundSet = new HashSet<>();
                        Set<String> changeSet = new HashSet<>();
                        Set<String> chChangeSet = new HashSet<>();
                        Set<String> inChangeSet = new HashSet<>();
                        for (String cabin : cabins) {
                            //仓位
                            MoCabinInfo cinfo = new MoCabinInfo();
                            //餐食
                            String meal = flt.meal;
                            if (!StringHelper.isNullOrEmpty(meal)) {
                                String mealSub = meal.substring(0, 1);
                                String mealSubTwo = meal.substring(1);
                                if (mealSubTwo != null && !mealSubTwo.equals("")) {
                                    cinfo.Meal = meal(mealSubTwo);
                                } else {
                                    cinfo.Meal = meal(mealSub);
                                }
                            }else {
                                cinfo.Meal = "无";
                            }
                            String[] split = cabin.split(":");
                            cinfo.Cabin = split[0];
                            if ("A".equals(split[1])) {
                                cinfo.CabinLeftDesc = "座位充足";
                            } else {
                                cinfo.CabinLeftDesc = String.valueOf(Integer.parseInt(split[1]));
                            }

                            //仓位价格处理
                            List<PFare> finalPFare = pFare;
                            List<NFare> finalNFare = nFare;
                            ps.forEach(item -> {
                                String disAmt = item.disAmt;
                                item.Routs.forEach(routs -> {
                                    if (routs.routStr.equals(flt.airline + flt.fltNo + ":" + cinfo.Cabin)) {

                                        //燃油和基建
                                        String[] cnTax = getTaxInfo(item.Taxes.Tax.get(0).taxComponent);
                                        String[] yqTax = getTaxInfo(item.Taxes.Tax.get(1).taxComponent);
                                        if (item.passengerType.equals("AD")) {
                                            info.AirportTax = new BigDecimal(cnTax[0]);
                                            info.FuelTax = new BigDecimal(yqTax[0]);
                                        } else if (item.passengerType.equals("CH")) {
                                            info.ChildAirportTax = new BigDecimal(cnTax[0]);
                                            info.ChildFuelTax = new BigDecimal(yqTax[0]);
                                        } else if (item.passengerType.equals("IN")) {
                                            info.InfantAirportTax = new BigDecimal(cnTax[0]);
                                            info.InfantFuelTax = new BigDecimal(yqTax[0]);
                                        }

                                        if (item.passengerType.equals("AD")) {
                                            cinfo.CallCenterAmountInfo.OrgTicketAmount = new BigDecimal(disAmt);
                                        } else if (item.passengerType.equals("CH")) {
                                            cinfo.CallCenterAmountInfo.OrgChdTicketAmount = new BigDecimal(disAmt);
                                        } else if (item.passengerType.equals("IN")) {
                                            cinfo.CallCenterAmountInfo.OrgIftTicketAmount = new BigDecimal(disAmt);
                                        }
                                        cinfo.CallCenterAmountInfo.TicketAmount = new BigDecimal(item.FCs.FC.get(0).YFares.yFareAmount);
                                        String cabinLevelId = item.FCs.FC.get(0).FareBind.fareRPH;
                                        getCabinLevel(cabinLevelId, cinfo, finalPFare, finalNFare);

                                        List<String> refundRph = null;
                                        List<String> changeRph = null;
                                        if (item.FCs.FC.size() > 1) {
                                            if (item.FCs.FC.get(1).RefundDetailRph != null && item.FCs.FC.get(1).ReissueDetailRph != null) {
                                                refundRph = item.FCs.FC.get(1).RefundDetailRph;
                                                changeRph = item.FCs.FC.get(1).ReissueDetailRph;
                                            } else {
                                                refundRph = item.FCs.FC.get(0).RefundDetailRph;
                                                changeRph = item.FCs.FC.get(0).ReissueDetailRph;
                                            }
                                            if (item.FCs.FC.get(1).SecInfo.size() > 1) {
                                                if (item.passengerType.equals("AD")) {
                                                    if (item.FCs.FC.get(1).SecInfo.get(1).Baggage != null)
                                                        cinfo.CabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(1).Baggage;
                                                    else if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                        cinfo.CabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                    else if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null) {
                                                        cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                    } else if (item.FCs.FC.get(0).SecInfo.get(0).Baggage != null) {
                                                        cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    }
                                                } else if (item.passengerType.equals("CH")) {
                                                    if (item.FCs.FC.get(1).SecInfo.get(1).Baggage != null)
                                                        cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(1).Baggage;
                                                    else if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                        cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                    else if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null) {
                                                        cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                    } else if (item.FCs.FC.get(0).SecInfo.get(0).Baggage != null) {
                                                        cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                    }
                                                }
                                            } else {
                                                if (item.passengerType.equals("AD")) {
                                                    if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                        cinfo.CabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                    else
                                                        cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                } else if (item.passengerType.equals("CH")) {
                                                    if (item.FCs.FC.get(1).SecInfo.get(0).Baggage != null)
                                                        cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                                    else
                                                        cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                }
                                            }
                                        } else {
                                            refundRph = item.FCs.FC.get(0).RefundDetailRph;
                                            changeRph = item.FCs.FC.get(0).ReissueDetailRph;
                                            if (item.passengerType.equals("AD")) {
                                                if (item.FCs.FC.get(0).SecInfo.size() > 1) {
                                                    if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null)
                                                        cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                    else
                                                        cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                } else {
                                                    cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                }
                                            } else if (item.passengerType.equals("CH")) {
                                                if (item.FCs.FC.get(0).SecInfo.size() > 1) {
                                                    if (item.FCs.FC.get(0).SecInfo.get(1).Baggage != null)
                                                        cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(1).Baggage;
                                                    else
                                                        cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                } else {
                                                    cinfo.ChdCabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                                }
                                            }

                                        }

                                        if (cinfo.CabinRule.refundRph.size() == 0) {
                                            if (item.passengerType.equals("AD")) {
                                                if (refundRph.size() > 0) {
                                                    if (refundSet.add(info.FlightNo + cinfo.Cabin + refundRph))
                                                        cinfo.CabinRule.refundRph.addAll(refundRph);
                                                }
                                            } else if (item.passengerType.equals("CH")) {
                                                if (refundRph.size() > 0) {
                                                    if (chRefundSet.add(info.FlightNo + cinfo.Cabin + refundRph))
                                                        cinfo.ChdCabinRule.refundRph.addAll(refundRph);
                                                }
                                            } else if (item.passengerType.equals("IN")) {
                                                if (refundRph.size() > 0) {
                                                    if (inRefundSet.add(info.FlightNo + cinfo.Cabin + refundRph))
                                                        cinfo.IftCabinRule.refundRph.addAll(refundRph);
                                                }
                                            }
                                        }
                                        if (cinfo.CabinRule.changeRph.size() == 0) {
                                            if (item.passengerType.equals("AD")) {
                                                if (changeRph.size() > 0) {
                                                    if (changeSet.add(info.FlightNo + cinfo.Cabin + changeRph))
                                                        cinfo.CabinRule.changeRph.addAll(changeRph);
                                                }
                                            } else if (item.passengerType.equals("CH")) {
                                                if (changeRph.size() > 0) {
                                                    if (chChangeSet.add(info.FlightNo + cinfo.Cabin + changeRph))
                                                        cinfo.ChdCabinRule.changeRph.addAll(changeRph);
                                                }
                                            } else if (item.passengerType.equals("IN")) {
                                                if (changeRph.size() > 0) {
                                                    if (inChangeSet.add(info.FlightNo + cinfo.Cabin + changeRph))
                                                        cinfo.IftCabinRule.changeRph.addAll(changeRph);
                                                }
                                            }
                                        }
                                    }
                                });
                            });
                            if (StringHelper.isNullOrEmpty(cinfo.BaseCabin)) {
                                continue;
                            }
                            info.ListCabinInfo.add(cinfo);
                        }
                        if (info.ListCabinInfo.size() > 0) {
                            response.ListGoFlightInfo.add(info);
                        }
                    }

                }

                if (response.ListGoFlightInfo.size() > 0)
                    addRefundChangeRule(response.ListGoFlightInfo, refund, change);
                if (response.transferFlightInfo.size() > 0)
                    addRefundChangeRule(response.transferFlightInfo, refund, change);
            }

            //解析往返
            else {

                RoundFlightRes roundFlightRes = JSON.parseObject(jsonStr, RoundFlightRes.class);

                //响应错误
                FError err = roundFlightRes.FareInterface.Output.Result.Error;
                if (err != null) {
                    response.ErrorCode = err.code;
                    response.ErrorMsg = err.message;
                    return response;
                }

                //航班数据
                List<RAvJourney> avJourney = roundFlightRes.FareInterface.Output.Result.FlightShopResult.AvJourneys.AvJourney;
                //仓位价格
                List<RPS> rpsList = roundFlightRes.FareInterface.Output.Result.FlightShopResult.PSn.PS;
                //舱位等级
                RPFares fares = roundFlightRes.FareInterface.Output.Result.FlightShopResult.PFares;
                RPFares rpFares = roundFlightRes.FareInterface.Output.Result.FlightShopResult.NFares;
                //退票规则
                List<FSRefundDetailDisplay> refund = roundFlightRes.FareInterface.Output.Result.FlightShopResult.FsRefundRuleDisplay.FSRefundDetailDisplay;
                //改签规则
                List<FSReissueDetailDisplay> change = roundFlightRes.FareInterface.Output.Result.FlightShopResult.FsReissueRuleDisplay.FSReissueDetailDisplay;

                //去程航班
                List<RAvOpt> goAvOpt = avJourney.get(0).AvOpt;

                //返程航班
                List<RAvOpt> backAvOpt = avJourney.get(1).AvOpt;

                List<MoFlightInfo> goFlightInfoList = getMoFlightInfo(goAvOpt, rpsList, moRequest.GoSearchWhere.DepDate, fares, rpFares, "go", moRequest.hasChildren);
                List<MoFlightInfo> goFlightInfos = addRefundChangeRule(goFlightInfoList, refund, change);
                response.ListGoFlightInfo = goFlightInfos;

                List<MoFlightInfo> backFlightInfoList = getMoFlightInfo(backAvOpt, rpsList, moRequest.BackSearchWhere.DepDate, fares, rpFares, "back", moRequest.hasChildren);
                List<MoFlightInfo> backFlightInfos = addRefundChangeRule(backFlightInfoList, refund, change);
                response.ListBackFlightInfo = backFlightInfos;



//
//                //航班组合
//                List<RPS> ps = roundFlightRes.FareInterface.Output.Result.FlightShopResult.PSn.PS;

            }

        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            e.printStackTrace();
            return response;
        }

        return response;

    }

    /**
     * 退改签规则处理
     * @param flightInfo
     * @param refund
     * @param change
     * @return
     */
    private List<MoFlightInfo> addRefundChangeRule(List<MoFlightInfo> flightInfo, List<FSRefundDetailDisplay> refund, List<FSReissueDetailDisplay> change) {
        for (MoFlightInfo info : flightInfo) {
            Set<String> refundSet = new HashSet<>();
            Set<String> chRefundSet = new HashSet<>();
            Set<String> inRefundSet = new HashSet<>();
            Set<String> changeSet = new HashSet<>();
            Set<String> chChangeSet = new HashSet<>();
            Set<String> inChangeSet = new HashSet<>();
            for (MoCabinInfo cinfo : info.ListCabinInfo) {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                List<CabinRefundChangeRules> refundRulesList = new ArrayList<>();
                List<CabinRefundChangeRules> chRefundRulesList = new ArrayList<>();
                List<CabinRefundChangeRules> inRefundRulesList = new ArrayList<>();
                List<CabinRefundChangeRules> changeRulesList = new ArrayList<>();
                List<CabinRefundChangeRules> chChangeRulesList = new ArrayList<>();
                List<CabinRefundChangeRules> inChangeRulesList = new ArrayList<>();
                Calendar calendar = new GregorianCalendar();

                //成人退改签规则处理
                if (cinfo.CallCenterAmountInfo.OrgTicketAmount != null) {
                    if (cinfo.CabinRule.refundRph.size() > 0) {
                        cinfo.CabinRule.refundRph.forEach(refundRules -> {
                            for (FSRefundDetailDisplay display : refund) {
                                if (display.RefundDetailRph.equals(refundRules)) {
                                    CabinRefundChangeRules refundChangeRules = new CabinRefundChangeRules();
                                    if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")) {
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -4);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && !display.LastDepartureTime.equals("-1")  && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        Date time = calendar.getTime();
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(time) + "--" + dateFormat.format(calendar.getTime());
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")  && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "前";
                                    } else if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("0") && !display.LastDepartureTime.equals("-1")) {
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 1) {
                                        refundChangeRules.time = dateFormat.format(info.DepDate) + "后";
                                    }
                                    if (display.RefundPercent.equals("-1") || display.RefundPercent.equals("0")) {
                                        refundChangeRules.refundRules = "免费退票";
                                    } else {
                                        BigDecimal divide = new BigDecimal(display.RefundPercent).divide(new BigDecimal(100));
                                        BigDecimal multiply = cinfo.CallCenterAmountInfo.OrgTicketAmount.multiply(divide);
                                        refundChangeRules.refundRules = "￥ " + multiply + "/人";
                                    }
                                    refundRulesList.add(refundChangeRules);
                                }
                                if (cinfo.CabinRule.refundRph.size() == refundRulesList.size())
                                    break;
                            }
                        });
                    }

                    if (cinfo.CabinRule.changeRph.size() > 0) {
                        cinfo.CabinRule.changeRph.forEach(changeRules -> {
                            for (FSReissueDetailDisplay display : change) {
                                if (display.ReissueDetailRph.equals(changeRules)) {
                                    CabinRefundChangeRules refundChangeRules = new CabinRefundChangeRules();
                                    if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")) {
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -4);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && !display.LastDepartureTime.equals("-1") && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        Date time = calendar.getTime();
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(time) + "--" + dateFormat.format(calendar.getTime());
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")  && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "前";
                                    } else if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("0") && !display.LastDepartureTime.equals("-1")) {
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 1) {
                                        refundChangeRules.time = dateFormat.format(info.DepDate) + "后";
                                    }
                                    if (display.ReissuePercent.equals("-1") || display.ReissuePercent.equals("0")) {
                                        refundChangeRules.changeRules = "免费变更";
                                    } else {
                                        BigDecimal divide = new BigDecimal(display.ReissuePercent).divide(new BigDecimal(100));
                                        BigDecimal multiply = cinfo.CallCenterAmountInfo.OrgTicketAmount.multiply(divide);
                                        refundChangeRules.changeRules = "￥ " + multiply + "/人";
                                    }
                                    changeRulesList.add(refundChangeRules);
                                }
                                if (cinfo.CabinRule.changeRph.size() == changeRulesList.size())
                                    break;
                            }
                        });
                    }

                    if (cinfo.CabinRule.refundChangeRules.size() == 0) {
                        if (refundRulesList.size() > 0) {
                            refundRulesList.forEach(refundRules -> {
                                Map<String, Object> map = new HashMap<>();
                                map.put("time", refundRules.time);
                                map.put("refundRules", refundRules.refundRules);
                                if (refundSet.add(refundRules.time + info.FlightNo + cinfo.Cabin))
                                    cinfo.CabinRule.refundChangeRules.add(map);
                            });
                        }
                    }
                    if (cinfo.CabinRule.changeRules.size() == 0) {
                        if (changeRulesList.size() > 0) {
                            changeRulesList.forEach(changeRules -> {
                                Map<String, Object> map = new HashMap<>();
                                map.put("time", changeRules.time);
                                map.put("changeRules", changeRules.changeRules);
                                if (changeSet.add(changeRules.time + info.FlightNo + cinfo.Cabin))
                                    cinfo.CabinRule.changeRules.add(map);
                            });
                        }
                    }
                }

                //儿童退改签规则处理
                if (cinfo.CallCenterAmountInfo.OrgChdTicketAmount != null) {
                    if (cinfo.ChdCabinRule.refundRph.size() > 0) {
                        cinfo.ChdCabinRule.refundRph.forEach(refundRules -> {
                            for (FSRefundDetailDisplay display : refund) {
                                if (display.RefundDetailRph.equals(refundRules)) {
                                    CabinRefundChangeRules refundChangeRules = new CabinRefundChangeRules();
                                    if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")) {
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -4);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && !display.LastDepartureTime.equals("-1")  && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        Date time = calendar.getTime();
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(time) + "--" + dateFormat.format(calendar.getTime());
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")  && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "前";
                                    } else if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("0") && !display.LastDepartureTime.equals("-1")) {
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 1) {
                                        refundChangeRules.time = dateFormat.format(info.DepDate) + "后";
                                    }
                                    if (display.RefundPercent.equals("-1") || display.RefundPercent.equals("0")) {
                                        refundChangeRules.refundRules = "免费退票";
                                    } else {
                                        BigDecimal divide = new BigDecimal(display.RefundPercent).divide(new BigDecimal(100));
                                        BigDecimal multiply = cinfo.CallCenterAmountInfo.OrgTicketAmount.multiply(divide);
                                        refundChangeRules.refundRules = "￥ " + multiply + "/人";
                                    }
                                    chRefundRulesList.add(refundChangeRules);
                                }
                                if (cinfo.CabinRule.refundRph.size() == chRefundRulesList.size())
                                    break;
                            }
                        });
                    }

                    if (cinfo.ChdCabinRule.changeRph.size() > 0) {
                        cinfo.ChdCabinRule.changeRph.forEach(changeRules -> {
                            for (FSReissueDetailDisplay display : change) {
                                if (display.ReissueDetailRph.equals(changeRules)) {
                                    CabinRefundChangeRules refundChangeRules = new CabinRefundChangeRules();
                                    if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")) {
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -4);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && !display.LastDepartureTime.equals("-1") && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        Date time = calendar.getTime();
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(time) + "--" + dateFormat.format(calendar.getTime());
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")  && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "前";
                                    } else if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("0") && !display.LastDepartureTime.equals("-1")) {
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 1) {
                                        refundChangeRules.time = dateFormat.format(info.DepDate) + "后";
                                    }
                                    if (display.ReissuePercent.equals("-1") || display.ReissuePercent.equals("0")) {
                                        refundChangeRules.changeRules = "免费变更";
                                    } else {
                                        BigDecimal divide = new BigDecimal(display.ReissuePercent).divide(new BigDecimal(100));
                                        BigDecimal multiply = cinfo.CallCenterAmountInfo.OrgTicketAmount.multiply(divide);
                                        refundChangeRules.changeRules = "￥ " + multiply + "/人";
                                    }
                                    chChangeRulesList.add(refundChangeRules);
                                }
                                if (cinfo.ChdCabinRule.changeRph.size() == chChangeRulesList.size())
                                    break;
                            }
                        });
                    }

                    if (cinfo.ChdCabinRule.refundChangeRules.size() == 0) {
                        if (chRefundRulesList.size() > 0) {
                            chRefundRulesList.forEach(refundRules -> {
                                Map<String, Object> map = new HashMap<>();
                                map.put("time", refundRules.time);
                                map.put("refundRules", refundRules.refundRules);
                                if (chRefundSet.add(refundRules.time + info.FlightNo + cinfo.Cabin))
                                    cinfo.ChdCabinRule.refundChangeRules.add(map);
                            });
                        }
                    }
                    if (cinfo.ChdCabinRule.changeRules.size() == 0) {
                        if (chChangeRulesList.size() > 0) {
                            chChangeRulesList.forEach(changeRules -> {
                                Map<String, Object> map = new HashMap<>();
                                map.put("time", changeRules.time);
                                map.put("changeRules", changeRules.changeRules);
                                if (chChangeSet.add(changeRules.time + info.FlightNo + cinfo.Cabin))
                                    cinfo.ChdCabinRule.changeRules.add(map);
                            });
                        }
                    }
                }

                //婴儿退改签规则处理
                if (cinfo.CallCenterAmountInfo.OrgIftTicketAmount != null) {
                    if (cinfo.IftCabinRule.refundRph.size() > 0) {
                        cinfo.IftCabinRule.refundRph.forEach(refundRules -> {
                            for (FSRefundDetailDisplay display : refund) {
                                if (display.RefundDetailRph.equals(refundRules)) {
                                    CabinRefundChangeRules refundChangeRules = new CabinRefundChangeRules();
                                    if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")) {
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -4);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && !display.LastDepartureTime.equals("-1")  && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        Date time = calendar.getTime();
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(time) + "--" + dateFormat.format(calendar.getTime());
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")  && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "前";
                                    } else if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("0") && !display.LastDepartureTime.equals("-1")) {
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 1) {
                                        refundChangeRules.time = dateFormat.format(info.DepDate) + "后";
                                    }
                                    if (display.RefundPercent.equals("-1") || display.RefundPercent.equals("0")) {
                                        refundChangeRules.refundRules = "免费退票";
                                    } else {
                                        BigDecimal divide = new BigDecimal(display.RefundPercent).divide(new BigDecimal(100));
                                        BigDecimal multiply = cinfo.CallCenterAmountInfo.OrgTicketAmount.multiply(divide);
                                        refundChangeRules.refundRules = "￥ " + multiply + "/人";
                                    }
                                    inRefundRulesList.add(refundChangeRules);
                                }
                                if (cinfo.IftCabinRule.refundRph.size() == inRefundRulesList.size())
                                    break;
                            }
                        });
                    }

                    if (cinfo.IftCabinRule.changeRph.size() > 0) {
                        cinfo.IftCabinRule.changeRph.forEach(changeRules -> {
                            for (FSReissueDetailDisplay display : change) {
                                if (display.ReissueDetailRph.equals(changeRules)) {
                                    CabinRefundChangeRules refundChangeRules = new CabinRefundChangeRules();
                                    if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")) {
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -4);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && !display.LastDepartureTime.equals("-1") && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        Date time = calendar.getTime();
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(time) + "--" + dateFormat.format(calendar.getTime());
                                    } else if (display.DepartureTimeType == 0 && !display.FirstDepartureTime.equals("-1") && display.LastDepartureTime.equals("-1")  && !display.FirstDepartureTime.equals("0")) {
                                        int departureTime = Integer.parseInt(display.FirstDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -departureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "前";
                                    } else if (display.DepartureTimeType == 0 && display.FirstDepartureTime.equals("0") && !display.LastDepartureTime.equals("-1")) {
                                        int lastDepartureTime = Integer.parseInt(display.LastDepartureTime);
                                        calendar.setTime(info.DepDate);
                                        calendar.add(Calendar.HOUR_OF_DAY, -lastDepartureTime);
                                        refundChangeRules.time = dateFormat.format(calendar.getTime()) + "--" + dateFormat.format(info.DepDate);
                                    } else if (display.DepartureTimeType == 1) {
                                        refundChangeRules.time = dateFormat.format(info.DepDate) + "后";
                                    }
                                    if (display.ReissuePercent.equals("-1") || display.ReissuePercent.equals("0")) {
                                        refundChangeRules.changeRules = "免费变更";
                                    } else {
                                        BigDecimal divide = new BigDecimal(display.ReissuePercent).divide(new BigDecimal(100));
                                        BigDecimal multiply = cinfo.CallCenterAmountInfo.OrgTicketAmount.multiply(divide);
                                        refundChangeRules.changeRules = "￥ " + multiply + "/人";
                                    }
                                    inChangeRulesList.add(refundChangeRules);
                                }
                                if (cinfo.IftCabinRule.changeRph.size() == inChangeRulesList.size())
                                    break;
                            }
                        });
                    }

                    if (cinfo.IftCabinRule.refundChangeRules.size() == 0) {
                        if (inRefundRulesList.size() > 0) {
                            inRefundRulesList.forEach(refundRules -> {
                                Map<String, Object> map = new HashMap<>();
                                map.put("time", refundRules.time);
                                map.put("refundRules", refundRules.refundRules);
                                if (inRefundSet.add(refundRules.time + info.FlightNo + cinfo.Cabin))
                                    cinfo.IftCabinRule.refundChangeRules.add(map);
                            });
                        }
                    }
                    if (cinfo.IftCabinRule.changeRules.size() == 0) {
                        if (inChangeRulesList.size() > 0) {
                            inChangeRulesList.forEach(changeRules -> {
                                Map<String, Object> map = new HashMap<>();
                                map.put("time", changeRules.time);
                                map.put("changeRules", changeRules.changeRules);
                                if (inChangeSet.add(changeRules.time + info.FlightNo + cinfo.Cabin))
                                    cinfo.IftCabinRule.changeRules.add(map);
                            });
                        }
                    }
                }
            }
        }
        return flightInfo;
    }

    public void addRefundRule(List<CabinRefundChangeRules> refundRulesList, MoCabinInfo cinfo)
    {
        for (CabinRefundChangeRules refundRule : refundRulesList)
        {
            Map<String, Object> map = new HashMap<>();
            map.put("time", refundRule.time);
            map.put("refundRules", refundRule.refundRules);
            if (cinfo.CabinRule == null || cinfo.CabinRule.refundChangeRules == null || refundRule.time==null || refundRule.refundRules==null)
            {
                System.out.println(cinfo);
            }
            Map<String, Object> mData = cinfo.CabinRule.refundChangeRules.stream().filter(item -> item.get("time").equals(refundRule.time) && item.get("refundRules").equals(refundRule.refundRules)).findFirst().orElse(null);
            if (mData == null)
            {
                cinfo.CabinRule.refundChangeRules.add(map);
            }
        }
    }


    /**
     * 查询航班详情
     */
    public FlightInfoVo searchFightDetails(FlightInfoReqVo vo) {

        FlightInfoVo response = new FlightInfoVo();

        try {
            //航班信息

            OTA_AirDetailsRQ airDetailsRQ = new OTA_AirDetailsRQ();

            POS pos = new POS();
            Source source = new Source();
            source.PseudoCityCode = OFFICE;
            ;
            pos.Source = source;
            airDetailsRQ.POS = pos;

            //航班
            AirDetail detail = new AirDetail();
            detail.DepartureDate = vo.getDepDate();
            detail.FlightNumber = vo.getFightNo();
            detail.Cabin = vo.getCabin();

            //航司
            Airline airline = new Airline();
            airline.Code = vo.getAirlineCode();
            detail.Airline = airline;

            //抵达机场三字码
            DepartureAirport departureAirport = new DepartureAirport();
            departureAirport.LocationCode = vo.getDstAirport();
            detail.DepartureAirport = departureAirport;
            //出发机场三字码
            ArrivalAirport arrivalAirport = new ArrivalAirport();
            arrivalAirport.LocationCode = vo.getOrgAirport();
            detail.ArrivalAirport = arrivalAirport;

            airDetailsRQ.AirDetail = detail;


            //序列化
            XmlMapper xmlMapper = new XmlMapper();

            String xmlStr = xmlMapper.writeValueAsString(airDetailsRQ);
            String str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + xmlStr;


            //发送请求
            String resp = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirDetails", str);

            //返回响应结果
            OTA_AirDetailsRS rs = xmlMapper.readValue(resp, OTA_AirDetailsRS.class);

            //处理响应错误结果
            if (rs.Errors != null) {
                response.setCode(rs.Errors.Error.Code);
                response.setMessage(rs.Errors.Error.ShortTextZH);
                return response;
            }

            //响应正常
            if (rs.FlightDetails != null) {

                //航班号
                response.setFlightNo(rs.FlightDetails.FlightLegDetails.FlightNumber);
                //经停次数
                response.setStopCount(rs.FlightDetails.StopQuantity);
                String arrDate = rs.FlightDetails.FlightLegDetails.ArrivalDateTime.replace("T", " ");
                //抵达时间
                response.setArrDate(arrDate);
                String depDate = rs.FlightDetails.FlightLegDetails.DepartureDateTime.replace("T", " ");
                //出发时间
                response.setDepDate(depDate);
                //抵达三字码
                response.setDstAirport(rs.FlightDetails.FlightLegDetails.DepartureAirport.LocationCode);
                String dstAirportName = getAirPortNameByRirPortCode(response.getDstAirport());
                response.setDstAirportName(dstAirportName);
                //出发发三字码
                response.setOrgAirport(rs.FlightDetails.FlightLegDetails.ArrivalAirport.LocationCode);
                String orgAirportName = getAirPortNameByRirPortCode(response.getOrgAirport());
                response.setOrgAirportName(orgAirportName);
                //机型
                response.setPlaneStyle(rs.FlightDetails.FlightLegDetails.Equipment.AirEquipType);
                //仓位
                response.setCabin(rs.FlightDetails.FlightLegDetails.MarketingCabinAvailability.CabinType);
                //航司
                response.setAirline(rs.FlightDetails.FlightLegDetails.MarketingAirline.Code);
                //公里数
                response.setTPM(rs.FlightDetails.TotalMiles);

            } else {
                response.setMessage("未查询到相关数据 , 请重新查询");
                return response;
            }

        } catch (Exception ex) {
            response.setCode(EnumHelper.ReturnCode.系统异常代码.toString());
            response.setMessage(ex.getMessage());
        }
        return response;
    }


    public FightStopResVo searchStopFightInfo(FightStopReqVo stopReqVo) {
        String requestStr = String.format("<OTA_AirBriefRQ xmlns=\"http://espeed.travelsky.com\">\n" +
                "    <POS>\n" +
                "        <Source PseudoCityCode=\"%s\" />\n" +
                "    </POS>\n" +
                "    <AirBrief>\n" +
                "        <Airline Code=\"%s\" />\n" +
                "        <FlightNumber>%s</FlightNumber>\n" +
                "        <DepartureDate>%s</DepartureDate>\n" +
                "    </AirBrief>\n" +
                "</OTA_AirBriefRQ>", OFFICE, stopReqVo.getCode(), stopReqVo.getFlightNo(), stopReqVo.getDate());

        FightStopResVo resVo = null;

        try {
            //发送请求
            String resp = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirBrief", requestStr);

            XElement root = XElement.loadXml(resp);

            resVo = new FightStopResVo();

            if (root.toString().contains("Errors")) {
                XElement ResultEnt = root.element("Errors").element("Error");
                resVo.setCode(ResultEnt.getAttributeValue("Code"));
                resVo.setMsg(ResultEnt.getAttributeValue("ShortTextZH"));
                return resVo;
            }

            //处理数据
            XElement flightBrief = root.element("FlightBrief");
            resVo.setStopNum(flightBrief.getAttributeValue("StopQuantity"));
            resVo.setDepartureDate(flightBrief.getAttributeValue("DepartureDate"));

            //航节信息
            List<XElement> flightLegBrief = flightBrief.elements("FlightLegBrief");

            List<FlightLegBrief> fg = new ArrayList<>();
            for (XElement xElement : flightLegBrief) {
                FlightLegBrief flightLeg = new FlightLegBrief();

                String flightNumber = xElement.getAttributeValue("FlightNumber");
                String departureDateTime = xElement.getAttributeValue("DepartureDateTime");
                String arrivalDateTime = xElement.getAttributeValue("ArrivalDateTime");
                String departureAirport = xElement.element("DepartureAirport").getAttributeValue("LocationCode");
                String arivalAirport = xElement.element("ArrivalAirport").getAttributeValue("LocationCode");
                String airEquipType = xElement.element("Equipment").getAttributeValue("AirEquipType");

                flightLeg.setAirEquipType(airEquipType);
                flightLeg.setArrivalAirport(arivalAirport);
                flightLeg.setDepartureAirport(departureAirport);
                flightLeg.setArrivalDateTime(arrivalDateTime.replace("T", " "));
                flightLeg.setDepartureDateTime(departureDateTime.replace("T", " "));
                flightLeg.setFlightNumber(flightNumber);
                flightLeg.setDepartureAirportName(getAirPortNameByRirPortCode(departureAirport));
                flightLeg.setArrivalAirportName(getAirPortNameByRirPortCode(arivalAirport));

                //计算飞行时长
                long diff = convertToDate(arrivalDateTime.replace("T", " "), "yyyy-MM-dd HH:mm:ss").getTime() - convertToDate(departureDateTime.replace("T", " "), "yyyy-MM-dd HH:mm:ss").getTime();
                long diffMinutes = diff / (60 * 1000) % 60;
                long diffHours = diff / (60 * 60 * 1000) % 24;

                String flightTimes = "";
                if (diffHours == 0) {
                    flightTimes = diffMinutes + "分钟";
                } else if (diffMinutes == 0) {
                    flightTimes = diffHours + "小时";
                } else if (diffHours != 0 && diffMinutes != 0) {
                    flightTimes = diffHours + "小时" + diffMinutes + "分钟";
                }

                flightLeg.setFlightTimes(flightTimes.replace("-", ""));

                fg.add(flightLeg);
            }

            resVo.setFlightLegBriefs(fg);

        } catch (Exception e) {
            resVo.setCode(String.valueOf(EnumHelper.ReturnCode.系统异常代码.getValue()));
            resVo.setMsg(EnumHelper.ReturnCode.系统异常代码.toString());
            return resVo;
        }

        return resVo;
    }

    /**
     * 查询实时仓位
     *
     * @param moRequest
     * @return ·
     */
    public MoFlightSearchResponse realTimeFlightCheck(MoFlightSearchRequest moRequest) {

        MoFlightSearchResponse response = new MoFlightSearchResponse();
        String strResponseData = "";
        String strRequestData = "";

        try {

            //单程仓位查询
            if (moRequest.TripType == 1) {

                if (Strings.isNullOrEmpty(moRequest.GoSearchWhere.DepDate)) {
                    response.ErrorMsg = "出发日期不能为空";
                    return response;
                }

                //请求数据
                strRequestData = String.format("<OTA_AirAvailRQ>\n" +
                                "    <POS>\n" +
                                "        <Source Pid=\"40132\" PseudoCityCode=\"%s\" />\n" +
                                "    </POS>\n" +
                                "    <OriginDestinationInformation>\n" +
                                "        <OriginDestinationOptions>\n" +
                                "            <OriginDestinationOption>\n" +
                                "                <FlightSegment FlightNumber=\"%s\" DepartureDateTime=\"%s\">\n" +
                                "                    <DepartureAirport LocationCode=\"%s\" />\n" +
                                "                    <ArrivalAirport LocationCode=\"%s\" />\n" +
                                "                    <MarketingAirline Code=\"%s\" />\n" +
                                "                </FlightSegment>\n" +
                                "            </OriginDestinationOption>\n" +
                                "        </OriginDestinationOptions>\n" +
                                "    </OriginDestinationInformation>\n" +
                                "</OTA_AirAvailRQ>", OFFICE, moRequest.GoSearchWhere.FlightNo, moRequest.GoSearchWhere.DepDate,
                        moRequest.GoSearchWhere.DstAirport, moRequest.GoSearchWhere.OrgAirport, moRequest.GoSearchWhere.carrier);

                //发送请求
                strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirAvail/RealTime", strRequestData);


                XElement root = XElement.loadXml(strResponseData);

                if (root.toString().contains("Errors")) {
                    //错误处理
                    XElement ResultEnt = root.element("Errors");
                    XElement errorEnt = ResultEnt.element("Error");
                    response.ErrorMsg = errorEnt.getAttributeValue("ShortTextZH");
                    response.ErrorCode = errorEnt.getAttributeValue("Code");
                    return response;
                }

                //成功
                if (root.toString().contains("OriginDestinationInformation")) {
                    XElement information = root.element("OriginDestinationInformation").element("OriginDestinationOptions").element("OriginDestinationOption");

                    List<XElement> flight = information.elements("FlightSegment");
                    XElement xElement = flight.get(0);

                    response.ListGoFlightInfo = this.getRealTimeFlight(xElement);

                }

            }

            //往返
            else {

                if (Strings.isNullOrEmpty(moRequest.GoSearchWhere.DepDate)) {
                    response.ErrorMsg = "出发日期不能为空";
                    return response;
                }

                if (Strings.isNullOrEmpty(moRequest.BackSearchWhere.DepDate)) {
                    response.ErrorMsg = "返程日期不能为空";
                    return response;
                }

                //请求数据
                strRequestData = String.format("<OTA_AirAvailRQ>\n" +
                                "    <POS>\n" +
                                "        <Source PseudoCityCode=\"%s\" />\n" +
                                "    </POS>\n" +
                                "    <OriginDestinationInformation>\n" +
                                "        <OriginDestinationOptions>\n" +
                                "            <OriginDestinationOption>\n" +
                                "                <FlightSegment FlightNumber=\"%s\" DepartureDateTime=\"%s\">\n" +
                                "                    <DepartureAirport LocationCode=\"%s\" />\n" +
                                "                    <ArrivalAirport LocationCode=\"%s\" />\n" +
                                "                    <MarketingAirline Code=\"%s\" />\n" +
                                "                </FlightSegment>\n" +
                                "                <FlightSegment FlightNumber=\"%s\" DepartureDateTime=\"%s\">\n" +
                                "                    <DepartureAirport LocationCode=\"%s\" />\n" +
                                "                    <ArrivalAirport LocationCode=\"%s\" />\n" +
                                "                    <MarketingAirline Code=\"%s\" />\n" +
                                "                </FlightSegment>\n" +
                                "            </OriginDestinationOption>\n" +
                                "        </OriginDestinationOptions>\n" +
                                "    </OriginDestinationInformation>\n" +
                                "</OTA_AirAvailRQ>",
                        OFFICE, moRequest.GoSearchWhere.FlightNo, moRequest.GoSearchWhere.DepDate, moRequest.GoSearchWhere.DstAirport,
                        moRequest.GoSearchWhere.OrgAirport, moRequest.GoSearchWhere.carrier,
                        moRequest.BackSearchWhere.FlightNo, moRequest.BackSearchWhere.DepDate, moRequest.BackSearchWhere.DstAirport,
                        moRequest.BackSearchWhere.OrgAirport, moRequest.BackSearchWhere.carrier);


                //发送请求
                strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirAvail/RealTime", strRequestData);


                XElement root = XElement.loadXml(strResponseData);

                if (root.toString().contains("Errors")) {
                    //错误处理
                    XElement ResultEnt = root.element("Errors");
                    XElement errorEnt = ResultEnt.element("Error");
                    response.ErrorMsg = errorEnt.getAttributeValue("ShortTextZH");
                    response.ErrorCode = errorEnt.getAttributeValue("Code");
                    return response;
                }

                if (root.toString().contains("OriginDestinationInformation")) {
                    XElement information = root.element("OriginDestinationInformation").element("OriginDestinationOptions").element("OriginDestinationOption");
                    List<XElement> flightSegment = information.elements("FlightSegment");

                    //去程
                    XElement goxElement = flightSegment.get(0);
                    response.ListGoFlightInfo = this.getRealTimeFlight(goxElement);

                    //返程
                    XElement backXElement = flightSegment.get(1);
                    response.ListBackFlightInfo = this.getRealTimeFlight(backXElement);
                }

            }

        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            return response;
        }


        return response;
    }

    /**
     * 查询退改签说明
     *
     * @param moRequest 请求对象
     * @return
     */
    @Override
    public MoCabinTgqResponse _GetCabinTgq(MoCabinTgqRequest moRequest) {
        MoCabinTgqResponse response = new MoCabinTgqResponse();
        String strResponseData = "";
        String strRequestData = "";

        try {

            strRequestData = String.format("<RuleDisplayRQ>\n" +
                    "    <RuleDisplayRequest>\n" +
                    "        <Header>\n" +
                    "            <SysCode>CRS</SysCode>\n" +
                    "            <ChannelID>1E</ChannelID>\n" +
                    "            <Agency>\n" +
                    "                <Office>%s</Office>\n" +
                    "                <Pid>B12345</Pid>\n" +
                    "                <City>BJS</City>\n" +
                    "            </Agency>\n" +
                    "        </Header>\n" +
                    "        <RouteInfo>\n" +
                    "            <Origination>BJS</Origination>\n" +
                    "            <Destination>SHA</Destination>\n" +
                    "            <Sectors>\n" +
                    "                <Sector>\n" +
                    "                    <Carrier>CA</Carrier>\n" +
                    "                    <FlightNo>8363</FlightNo>\n" +
                    "                    <OperateCarrier>CA</OperateCarrier>\n" +
                    "                    <OperateFlightNo>8363</OperateFlightNo>\n" +
                    "                    <DepartureDateTime>01JUN2022/18:45</DepartureDateTime>\n" +
                    "                    <ArrivalDateTime>01JUN2022/21:00</ArrivalDateTime>\n" +
                    "                    <DepartureAirport>PKX</DepartureAirport>\n" +
                    "                    <ArrivalAirport>SHA</ArrivalAirport>\n" +
                    "                    <BookingClass>Y</BookingClass>\n" +
                    "                </Sector>\n" +
                    "            </Sectors>\n" +
                    "        </RouteInfo>\n" +
                    "        <FareInfo>\n" +
                    "            <DisplayFareAmount>1790</DisplayFareAmount>\n" +
                    "            <YFareAmount>1840</YFareAmount>\n" +
                    "        </FareInfo>\n" +
                    "        <RuleInfo>\n" +
                    "            <RuleID>FY1H</RuleID>\n" +
                    "        </RuleInfo>\n" +
                    "    </RuleDisplayRequest>\n" +
                    "</RuleDisplayRQ>", OFFICE);


            //发送请求
            strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirRuleDisplayPlus/D", strRequestData);


            // TODO 请求数据
            XElement root = XElement.loadXml(strResponseData);

            XElement result = root.element("RuleDisplayResult");

            XmlMapper xmlMapper = new XmlMapper();

            //错误
            if (result.toString().contains("Errors")) {
                response.ErrorCode = xmlMapper.readValue(result.element("Errors").element("Error").element("code").toString(), String.class);
                response.ErrorMsg = xmlMapper.readValue(result.element("Errors").element("Error").element("message").toString(), String.class);
                return response;
            }

            //正确数据
            XElement refundDisplays = result.element("RefundDisplays"); //退票规则
            MoCabinRule moCabinRule = new MoCabinRule();
            //规则描述
            moCabinRule.Refund = xmlMapper.readValue(refundDisplays.element("RefundDisplay").element("RefundDiscription").toString(), String.class);
            // moCabinRule.PsgType =  xmlMapper.readValue(refundDisplays.element("RefundDisplay").element("PassengerType").toString(),String.class);
            moCabinRule.Cabin = xmlMapper.readValue(refundDisplays.element("RefundDisplay").element("BookingClass").toString(), String.class);
            String journey = xmlMapper.readValue(refundDisplays.element("RefundDisplay").element("JourneyType").toString(), String.class);
            if ("OW".equals(journey)) {
                moCabinRule.LegNum = 1;
            } else {
                moCabinRule.LegNum = 2;
            }


            response.MoCabinRuleList.add(moCabinRule);


            XElement reissueDisplays = result.element("ReissueDisplays"); //改签规则
            MoCabinRule moCabin = new MoCabinRule();
            moCabin.Change = xmlMapper.readValue(reissueDisplays.element("ReissueDisplay").element("ReissueDiscription").toString(), String.class);
            moCabin.Cabin = xmlMapper.readValue(reissueDisplays.element("ReissueDisplay").element("BookingClass").toString(), String.class);
            String journeyType = xmlMapper.readValue(reissueDisplays.element("ReissueDisplay").element("JourneyType").toString(), String.class);
            if ("OW".equals(journeyType)) {
                moCabin.LegNum = 1;
            } else {
                moCabin.LegNum = 2;
            }

            response.MoCabinRuleList.add(moCabin);

        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            return response;
        }


        return response;
    }


    /**
     * 创建订单 (PNR预定)
     *
     * @param moRequest
     * @return
     */
    @Override
    public MoCreateOrderResponse _OrderCreate(MoCreateOrderRequest moRequest) {
        MoCreateOrderResponse response = new MoCreateOrderResponse();
        String strResponseData = "";
        String strRequestData = "";
        try {

            //单程
            if (moRequest.TripType == EnumHelper.TripType.单程.getValue()) {


                strRequestData = createPNR(moRequest);

                strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirBook", strRequestData);

                if (strResponseData.indexOf("RESP:INVALID FOID")!=-1)
                {
                    response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                    response.ErrorMsg = "存在无效的身份证信息";
                    response.IsSuccess = false;
                    return response;
                }
                XElement root = XElement.loadXml(strResponseData);

                if (root.toString().contains("Errors")) {
                    response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                    response.ErrorMsg = root.element("Errors").element("Error").getAttributeValue("ShortTextZH");
                    response.IsSuccess = false;
                    return response;
                }

                //解析数据
                String pnrId = root.element("AirReservation").element("BookingReferenceID").getAttributeValue("ID");

                // 根据生成的pnr提取结构化信息，查看票的状态是否可以出票,只有状态为HK的才可以出票
                XElement otaAirResRetByPnrId = getOTAAirResRetByPnrId(pnrId);
                String status = otaAirResRetByPnrId.element("AirResRet").element("FlightSegments").element("FlightSegment").getAttributeValue("Status");
                if ("HK".equals(status)) {
                    //预定成功
                    response.actionCode = status;
                    response.MainOrderID = pnrId;
                    response.IsSuccess = true;
                    response.ErrorMsg = "预定成功";
                } else {
                    response.IsSuccess = false;
                    response.MainOrderID = pnrId;
                    response.ErrorMsg = "预定失败！所选航班价格有变化，请取消此订单后，重新预定";
                }

            }

            //往返
            else {
                Date goDepDate = null;
                Date goArrDate = null;
                for (MoSegment moSegment : moRequest.ListGoSegment) {
                    goDepDate = moSegment.DepDate;
                    goArrDate = moSegment.ArrDate;
                }

                if (Strings.isNullOrEmpty(goDepDate.toString())) {
                    response.ErrorMsg = "出发时间不能为空";
                    return response;
                }
                if (Strings.isNullOrEmpty(goArrDate.toString())) {
                    response.ErrorMsg = "抵达时间不能为空";
                    return response;
                }

                //解析数据

                strRequestData = createPNR(moRequest);
                strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirBook", strRequestData);

                XElement root = XElement.loadXml(strResponseData);


                if (root.toString().contains("Errors")) {
                    response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                    response.ErrorMsg = root.element("Errors").element("Error").getAttributeValue("ShortTextZH");
                    response.IsSuccess = false;
                    return response;
                }

                String pnrId = root.element("AirReservation").element("BookingReferenceID").getAttributeValue("ID");

                // 根据生成的pnr提取结构化信息，查看票的状态是否可以出票,只有状态为HK的才可以出票
                XElement otaAirResRetByPnrId = getOTAAirResRetByPnrId(pnrId);
                List<XElement> FlightSegmentList = otaAirResRetByPnrId.element("AirResRet").element("FlightSegments").elements("FlightSegment");
                String goStatus = FlightSegmentList.get(0).getAttributeValue("Status");
                String backStatus = FlightSegmentList.get(1).getAttributeValue("Status");

                if ("HK".equals(goStatus) && "HK".equals(backStatus)) {
                    response.actionCode = goStatus;
                    response.MainOrderID = pnrId;
                    response.IsSuccess = true;
                    response.ErrorMsg = "预定成功";
                } else {
                    response.IsSuccess = false;
                    response.MainOrderID = pnrId;
                    response.ErrorMsg = "预定失败！所选航班价格有变化，请取消此订单后，重新预定";
                }

            }

        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            e.printStackTrace();
            return response;
        }

        return response;
    }


    /**
     * 查询订单信息 (PNR结构化信息提取)
     *
     * @param moRequest
     * @return
     */
    @Override
    public MoQueryOrderResponse _QueryOrderInfo(MoQueryOrderRequest moRequest) {
        MoQueryOrderResponse response = new MoQueryOrderResponse();

        try {

            XmlMapper xmlMapper = new XmlMapper();
            XElement xElement = getOTAAirResRetByPnrId(moRequest.OrderID);

            response.xElement = xElement.toString();

            if (xElement.toString().contains("Errors")) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH");
                response.IsSuccess = false;
                return response;
            }

            //解析数据
            //最晚出票时间(刚预定成功，没有走运价，支付出票)
            if (xElement.element("AirResRet").element("Ticketing").toString().contains("TicketTimeLimit")) {
                String TicketTimeLimit = xElement.element("AirResRet").element("Ticketing").getAttributeValue("TicketTimeLimit");
                TicketTimeLimit = TicketTimeLimit.replace("T", " ");
                Date date = convertToDate(TicketTimeLimit, "yyyy-MM-dd HH:mm:ss");
                response.IssDateLimit = date;
                //订单状态
                boolean flag = Boolean.valueOf(xElement.element("AirResRet").element("Ticketing").getAttributeValue("IsIssued"));
                response.OrderStatus = BooleanUtils.toInteger(flag);
                response.OrderStatusMsg = flag == true ? "已出票" : "未出票";

                //大编
                for (XElement element : xElement.element("AirResRet").elements("SpecialRemark")) {
                    if (element.element("Text").getValue().indexOf("CA/") != -1) {
                        String bigPNR = element.element("Text").getValue();
                        String[] str = bigPNR.split("/");
                        response.bigPnr = str[1];
                    }
                }
//                String bigPNR = xmlMapper.readValue(xElement.element("AirResRet").element("SpecialRemark").element("Text").toString(), String.class);
//                String[] str = bigPNR.split("/");
//                response.bigPnr = bigPNR = str[1];

                //pnr
                String pnr = xElement.element("AirResRet").element("BookingReferenceID").getAttributeValue("ID");

                // 乘客信息
                List<XElement> passengersList = xElement.element("AirResRet").elements("AirTraveler");

                //乘客人数
                response.PassengerNum = passengersList.size();


                //行程
                List<XElement> flightSegmentList = xElement.element("AirResRet").element("FlightSegments").elements("FlightSegment");
                for (XElement flightSegment : flightSegmentList) {
                    MoSegment moSegment = new MoSegment();
                    moSegment.Cabin = flightSegment.element("BookingClassAvail").getAttributeValue("ResBookDesigCode");
                    moSegment.FlightNo = flightSegment.getAttributeValue("FlightNumber");
                    String departureDateTime = flightSegment.getAttributeValue("DepartureDateTime");
                    departureDateTime = departureDateTime.replace("T", " ");
                    Date depDateTime = convertToDate(departureDateTime, "yyyy-MM-dd HH:mm:ss");
                    moSegment.DepDate = depDateTime;
                    moSegment.PNR = pnr;
                    String airline = xElement.element("AirResRet").element("FlightSegments").element("FlightSegment").element("MarketingAirline").getAttributeValue("Code");
                    moSegment.Airline = airline;
                    String orgAirport = xElement.element("AirResRet").element("FlightSegments").element("FlightSegment").element("DepartureAirport").getAttributeValue("LocationCode");
                    moSegment.OrgAirport = orgAirport;
                    String dstAirport = xElement.element("AirResRet").element("FlightSegments").element("FlightSegment").element("ArrivalAirport").getAttributeValue("LocationCode");
                    moSegment.DstAirport = dstAirport;
                    String orgTerminal = xElement.element("AirResRet").element("FlightSegments").element("FlightSegment").element("DepartureAirport").getAttributeValue("Terminal");
                    moSegment.orgTerminal = orgTerminal;
                    String dstTerminal = xElement.element("AirResRet").element("FlightSegments").element("FlightSegment").element("ArrivalAirport").getAttributeValue("Terminal");
                    moSegment.dstTerminal = dstTerminal;
                    String arrDate = flightSegment.getAttributeValue("ArrivalDateTime");
                    arrDate = arrDate.replace("T", " ");
                    Date arrDateTime = convertToDate(arrDate, "yyyy-MM-dd HH:mm:ss");
                    moSegment.ArrDate = arrDateTime;
                    response.ListGoSegment.add(moSegment);
                }

                //乘机人
                for (XElement passengers : passengersList) {
                    MoPassenger moPassenger = new MoPassenger();
                    String surName = xmlMapper.readValue(passengers.element("PersonName").element("Surname").toString(), String.class);
                    moPassenger.PassengerName = surName;
                    moPassenger.PNR = pnr;
                    List<XElement> elements = xElement.element("AirResRet").elements("SpecialServiceRequest");
                    XElement text = elements.get(0).element("Text");
                    JSONObject jsonObject = XML.toJSONObject(text.toString());
                    String valueOf = String.valueOf(jsonObject);
                    valueOf = valueOf.replace("{", "").replace("}", "").replace("\"", "");
                    valueOf = valueOf.substring(valueOf.indexOf(":") + 1).replace(" ", "");
                    valueOf = valueOf.substring(11, 29);
                    moPassenger.licenseNum = valueOf;

                    String ticketNo;
                    try {
                        ticketNo = xElement.element("AirResRet").element("TicketItemInfo").getAttributeValue("TicketNumber");
                    } catch (Exception e){
                        ticketNo = "";
                    }

                    moPassenger.TicketNo = ticketNo;
                    response.ListMoPassenger.add(moPassenger);

                }
                response.IsSuccess = true;
            } else {//已经走运价存储，出票

                //订单状态
                boolean flag = Boolean.valueOf(xElement.element("AirResRet").element("Ticketing").getAttributeValue("IsIssued"));
                response.OrderStatus = BooleanUtils.toInteger(flag);
                response.OrderStatusMsg = flag == true ? "已出票" : "未出票";

                //票号
                String ticketNum = xElement.element("AirResRet").element("TicketItemInfo").getAttributeValue("TicketNumber");
                response.OrderID = ticketNum;


                //pnr
                String pnr = xElement.element("AirResRet").element("BookingReferenceID").getAttributeValue("ID");

                for (XElement element : xElement.element("AirResRet").elements("SpecialRemark")) {
                    if (element.element("Text").getValue().indexOf("CA/") != -1) {
                        String bigPNR = element.element("Text").getValue();
                        String[] str = bigPNR.split("/");
                        response.bigPnr = str[1];
                    }
                }

                // 乘客信息
                List<XElement> passengersList = xElement.element("AirResRet").elements("AirTraveler");

                //乘客人数
                response.PassengerNum = passengersList.size();


                //行程
                List<XElement> flightSegmentList = xElement.element("AirResRet").element("FlightSegments").elements("FlightSegment");
                for (XElement flightSegment : flightSegmentList) {
                    MoSegment moSegment = new MoSegment();
                    moSegment.Cabin = flightSegment.element("BookingClassAvail").getAttributeValue("ResBookDesigCode");
                    moSegment.FlightNo = flightSegment.getAttributeValue("FlightNumber");
                    String departureDateTime = flightSegment.getAttributeValue("DepartureDateTime");
                    departureDateTime = departureDateTime.replace("T", " ");
                    Date depDateTime = convertToDate(departureDateTime, "yyyy-MM-dd HH:mm:ss");
                    moSegment.DepDate = depDateTime;
                    moSegment.PNR = pnr;
                    String airline = xElement.element("AirResRet").element("FlightSegments").element("FlightSegment").element("MarketingAirline").getAttributeValue("Code");
                    moSegment.Airline = airline;
                    String orgAirport = xElement.element("AirResRet").element("FlightSegments").element("FlightSegment").element("DepartureAirport").getAttributeValue("LocationCode");
                    moSegment.OrgAirport = orgAirport;
                    String dstAirport = xElement.element("AirResRet").element("FlightSegments").element("FlightSegment").element("ArrivalAirport").getAttributeValue("LocationCode");
                    moSegment.DstAirport = dstAirport;
                    String orgTerminal = xElement.element("AirResRet").element("FlightSegments").element("FlightSegment").element("DepartureAirport").getAttributeValue("Terminal");
                    moSegment.orgTerminal = orgTerminal;
                    String dstTerminal = xElement.element("AirResRet").element("FlightSegments").element("FlightSegment").element("ArrivalAirport").getAttributeValue("Terminal");
                    moSegment.dstTerminal = dstTerminal;
                    String arrDate = flightSegment.getAttributeValue("ArrivalDateTime");
                    arrDate = arrDate.replace("T", " ");
                    Date arrDateTime = convertToDate(arrDate, "yyyy-MM-dd HH:mm:ss");
                    moSegment.ArrDate = arrDateTime;
                    response.ListGoSegment.add(moSegment);
                }

                //乘机人
                for (XElement passengers : passengersList) {
                    MoPassenger moPassenger = new MoPassenger();
                    String surName = xmlMapper.readValue(passengers.element("PersonName").element("Surname").toString(), String.class);
                    moPassenger.PassengerName = surName;
                    moPassenger.PNR = pnr;
                    List<XElement> elements = xElement.element("AirResRet").elements("SpecialServiceRequest");
                    XElement text = elements.get(0).element("Text");
                    JSONObject jsonObject = XML.toJSONObject(text.toString());
                    String valueOf = String.valueOf(jsonObject);
                    valueOf = valueOf.replace("{", "").replace("}", "").replace("\"", "");
                    valueOf = valueOf.substring(valueOf.indexOf(":") + 1).replace(" ", "");
                    valueOf = valueOf.substring(11, 29);
                    moPassenger.licenseNum = valueOf;
                    String ticketNo = xElement.element("AirResRet").element("TicketItemInfo").getAttributeValue("TicketNumber");
                    moPassenger.TicketNo = ticketNo;
                    response.ListMoPassenger.add(moPassenger);

                }
                response.IsSuccess = true;
            }

        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            response.IsSuccess = false;
            return response;
        }

        return response;
    }


    /**
     * 取消PNR
     *
     * @param request
     * @return
     */
    @Override
    public MoCancelOrderResponse _CancelOrder(MoCancelOrderRequest request) {
        MoCancelOrderResponse response = new MoCancelOrderResponse();
        String strResponseData = "";
        String strRequestData = "";
        FlightOrderInfo flightOrderInfo = orderInfoService.selectFlightOrderInfo(request.ListOrderItem.OrderID); //获取订单主表信息
        try {
            strRequestData = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                    "<OTA_AirBookModifyRQ>\n" +
                    "    <POS>\n" +
                    "        <Source PseudoCityCode=\"%s\" />\n" +
                    "    </POS>\n" +
                    "    <AirBookModifyRQ ModificationType=\"PNR_CANCEL\" />\n" +
                    "    <AirReservation>\n" +
                    "        <BookingReferenceID ID=\"%s\" />\n" +
                    "    </AirReservation>\n" +
                    "</OTA_AirBookModifyRQ>", OFFICE, flightOrderInfo.getPnr());

            strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirBookModify", strRequestData);

            XElement root = XElement.loadXml(strResponseData);

            if (root.toString().contains("Errors")) {
                MoOrderItemResponse itemResponse = new MoOrderItemResponse();
                itemResponse.IsSuccess=false;
                itemResponse.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                itemResponse.ErrorMsg = "原航班PNR信息有误";
                response.ListOrderItem.add(itemResponse);
                return response;
            }

            XmlMapper xmlMapper = new XmlMapper();
            XElement airReservation = root.element("AirReservation");
            MoOrderItemResponse orderItemResponse = new MoOrderItemResponse();
            orderItemResponse.OrderID = airReservation.element("BookingReferenceID").getAttributeValue("ID");

            List<XElement> comment = airReservation.elements("Comment");
            String ok = xmlMapper.readValue(comment.get(0).toString(), String.class);
            String success = xmlMapper.readValue(comment.get(1).toString(), String.class);
            if ("success".equalsIgnoreCase(success) && "ok".equalsIgnoreCase(ok)) {
                orderItemResponse.IsSuccess = true;
            } else {
                orderItemResponse.IsSuccess = false;
            }
            response.ListOrderItem.add(orderItemResponse);

        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            return response;
        }

        return response;

    }

    /**
     * 改签取消PNR
     *
     * @param pnr
     * @return
     */
    public MoCancelOrderResponse _changeCancelOrder(String pnr) {
        MoCancelOrderResponse response = new MoCancelOrderResponse();
        String strResponseData = "";
        String strRequestData = "";
        try {
            strRequestData = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                    "<OTA_AirBookModifyRQ>\n" +
                    "    <POS>\n" +
                    "        <Source PseudoCityCode=\"%s\" />\n" +
                    "    </POS>\n" +
                    "    <AirBookModifyRQ ModificationType=\"PNR_CANCEL\" />\n" +
                    "    <AirReservation>\n" +
                    "        <BookingReferenceID ID=\"%s\" />\n" +
                    "    </AirReservation>\n" +
                    "</OTA_AirBookModifyRQ>", OFFICE, pnr);

            strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirBookModify", strRequestData);

            XElement root = XElement.loadXml(strResponseData);

            if (root.toString().contains("Errors")) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "原航班PNR信息有误";
                return response;
            }

            XmlMapper xmlMapper = new XmlMapper();
            XElement airReservation = root.element("AirReservation");
            MoOrderItemResponse orderItemResponse = new MoOrderItemResponse();
            orderItemResponse.OrderID = airReservation.element("BookingReferenceID").getAttributeValue("ID");

            List<XElement> comment = airReservation.elements("Comment");
            String ok = xmlMapper.readValue(comment.get(0).toString(), String.class);
            String success = xmlMapper.readValue(comment.get(1).toString(), String.class);
            if ("success".equalsIgnoreCase(success) && "ok".equalsIgnoreCase(ok)) {
                orderItemResponse.IsSuccess = true;
            } else {
                orderItemResponse.IsSuccess = false;
            }
            response.ListOrderItem.add(orderItemResponse);

        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            return response;
        }

        return response;

    }


    /**
     * 支付出票
     *
     * @param moRequest
     * @return
     */
    @Override
    public synchronized MoOrderPayResponse _OrderPay(MoOrderPayRequest moRequest) {

        MoOrderPayResponse response = new MoOrderPayResponse();
        XmlMapper xmlMapper = new XmlMapper();
        FlightOutticketLog outticketLog = new FlightOutticketLog();
        try {
            FlightOrderInfo orderInfo = orderInfoService.selectFlightOrderInfo(moRequest.OrderID); //获取订单主表信息
            R<Customer> customerR = customerService.getCustomerInfo(orderInfo.getCustomerId());
            outticketLog.setOrderId(Long.valueOf(moRequest.OrderID));
            outticketLog.setLoginfo("该订单准备在领达出票！");
            outticketLog.setCreateTime(new Date());
            outticketLogService.insertFlightOutticketLog(outticketLog);
            //支付之前先去计算运价,查出实际的支付价格
            CalculationResponse calculationResponse = this.calculationFreight(orderInfo.getPnr());
            if (!calculationResponse.isSuccess()) {
                response.ErrorMsg = "接口异常";
                response.IsSuccess = false;
                outticketLog.setLoginfo("该订单在领达出票失败！");
                outticketLog.setCreateTime(new Date());
                outticketLogService.insertFlightOutticketLog(outticketLog);

                FlightOrderException exception = new FlightOrderException();
                exception.setPassenger(orderInfo.getCustomerName());
                FlightOrderInfoTickets orderInfoTickets = new FlightOrderInfoTickets();
                orderInfoTickets.setOrderId(orderInfo.getOrderId());
                List<FlightOrderInfoTickets> ticketsList = orderInfoTicketsService.selectFlightOrderInfoTicketsList(orderInfoTickets);
                if (orderInfo.getTripType().equals("ow")) {
                    if (ticketsList.size() > 1) {
                        if (ticketsList.get(1).getTripType().equals("rt") || ticketsList.get(1).getTripType().equals("ot")) {
                            for (int i = 0; i < 2; i++) {
                                exception.setFlightno(ticketsList.get(i).getFlight());
                                exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                                exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                                exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                                exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                exception.setExceptionInfo("接口异常，运价计算失败");
                                exception.setSourceWay(orderInfo.getSourceTypeId());
                                exception.setStatus("untreated");
                                exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                exception.setOrderType("reserve");
                                exception.setPnr(orderInfo.getPnr());
                                flightOrderExceptionService.insertFlightOrderException(exception);
                            }
                        } else {
                            exception.setFlightno(ticketsList.get(0).getFlight());
                            exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                            exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                            exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                            exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                            exception.setExceptionInfo("接口异常，运价计算失败");
                            exception.setSourceWay(orderInfo.getSourceTypeId());
                            exception.setStatus("untreated");
                            exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                            exception.setOrderType("reserve");
                            exception.setPnr(orderInfo.getPnr());
                            flightOrderExceptionService.insertFlightOrderException(exception);
                        }
                    } else {
                        exception.setFlightno(ticketsList.get(0).getFlight());
                        exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                        exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                        exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                        exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                        exception.setExceptionInfo("接口异常，运价计算失败");
                        exception.setSourceWay(orderInfo.getSourceTypeId());
                        exception.setStatus("untreated");
                        exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                        exception.setOrderType("reserve");
                        exception.setPnr(orderInfo.getPnr());
                        flightOrderExceptionService.insertFlightOrderException(exception);
                    }
                } else if (orderInfo.getTripType().equals("rt")) {
                    for (int i = 0; i < 2; i++) {
                        exception.setFlightno(ticketsList.get(i).getFlight());
                        exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                        exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                        exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                        exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                        exception.setExceptionInfo("接口异常，运价计算失败");
                        exception.setSourceWay(orderInfo.getSourceTypeId());
                        exception.setStatus("untreated");
                        exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                        exception.setOrderType("reserve");
                        exception.setPnr(orderInfo.getPnr());
                        flightOrderExceptionService.insertFlightOrderException(exception);
                    }
                }
                orderInfo.setStatus(FlightOrderConstants.ticketingFail.getValue());
                orderInfoService.updateFlightOrderInfo(orderInfo);
                orderInfoTicketsService.updateFlightOrderInfoTicketsByOrderId(orderInfo.getOrderId(), FlightOrderConstants.ticketingFail.getValue());
                return response;
            }

            //判断价格是否发生变化
            BigDecimal PayAmountVo = orderInfo.getTicketAmount(); //页面传递的价格
            BigDecimal amount = new BigDecimal(calculationResponse.getAmount()).add(new BigDecimal(calculationResponse.getFuelTax())).add(new BigDecimal(calculationResponse.getAirportTax()));
            if (PayAmountVo.doubleValue() != amount.doubleValue()) {
                response.ErrorMsg = "您所选的航班价格发生变化，不能支付，请先取消此订单，重新预订！";
                response.IsSuccess = false;
                outticketLog.setLoginfo("您所选的航班价格发生变化，不能支付，请先取消此订单，重新预订！");
                outticketLog.setCreateTime(new Date());
                outticketLogService.insertFlightOutticketLog(outticketLog);

                FlightOrderException exception = new FlightOrderException();
                exception.setPassenger(orderInfo.getCustomerName());
                FlightOrderInfoTickets orderInfoTickets = new FlightOrderInfoTickets();
                orderInfoTickets.setOrderId(orderInfo.getOrderId());
                List<FlightOrderInfoTickets> ticketsList = orderInfoTicketsService.selectFlightOrderInfoTicketsList(orderInfoTickets);
                if (orderInfo.getTripType().equals("ow")) {
                    if (ticketsList.size() > 1) {
                        if (ticketsList.get(1).getTripType().equals("rt") || ticketsList.get(1).getTripType().equals("ot")) {
                            for (int i = 0; i < 2; i++) {
                                exception.setFlightno(ticketsList.get(i).getFlight());
                                exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                                exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                                exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                                exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                exception.setExceptionInfo("您所选的航班价格发生变化，不能支付，请先取消此订单，重新预订！");
                                exception.setSourceWay(orderInfo.getSourceTypeId());
                                exception.setStatus("untreated");
                                exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                exception.setOrderType("reserve");
                                exception.setPnr(orderInfo.getPnr());
                                flightOrderExceptionService.insertFlightOrderException(exception);
                            }
                        } else {
                            exception.setFlightno(ticketsList.get(0).getFlight());
                            exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                            exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                            exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                            exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                            exception.setExceptionInfo("您所选的航班价格发生变化，不能支付，请先取消此订单，重新预订！");
                            exception.setSourceWay(orderInfo.getSourceTypeId());
                            exception.setStatus("untreated");
                            exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                            exception.setOrderType("reserve");
                            exception.setPnr(orderInfo.getPnr());
                            flightOrderExceptionService.insertFlightOrderException(exception);
                        }
                    } else {
                        exception.setFlightno(ticketsList.get(0).getFlight());
                        exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                        exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                        exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                        exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                        exception.setExceptionInfo("您所选的航班价格发生变化，不能支付，请先取消此订单，重新预订！");
                        exception.setSourceWay(orderInfo.getSourceTypeId());
                        exception.setStatus("untreated");
                        exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                        exception.setOrderType("reserve");
                        exception.setPnr(orderInfo.getPnr());
                        flightOrderExceptionService.insertFlightOrderException(exception);
                    }
                } else if (orderInfo.getTripType().equals("rt")) {
                    for (int i = 0; i < 2; i++) {
                        exception.setFlightno(ticketsList.get(i).getFlight());
                        exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                        exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                        exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                        exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                        exception.setExceptionInfo("您所选的航班价格发生变化，不能支付，请先取消此订单，重新预订！");
                        exception.setSourceWay(orderInfo.getSourceTypeId());
                        exception.setStatus("untreated");
                        exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                        exception.setOrderType("reserve");
                        exception.setPnr(orderInfo.getPnr());
                        flightOrderExceptionService.insertFlightOrderException(exception);
                    }
                }
                orderInfo.setStatus(FlightOrderConstants.ticketingFail.getValue());
                orderInfoService.updateFlightOrderInfo(orderInfo);
                orderInfoTicketsService.updateFlightOrderInfoTicketsByOrderId(orderInfo.getOrderId(), FlightOrderConstants.ticketingFail.getValue());
                return response;
            }


            //判断走那个渠道进行出票，b2b、bsp

            Long orderId = orderInfo.getOrderId();//获取ID


            //获取订单详细信息
            List<FlightOrderInfoTickets> ticketList = orderInfoTicketsService.selectOrderInfoTicketByOrderId(orderId);


            //判断是否no位
            XElement xElement = getOTAAirResRetByPnrId(orderInfo.getPnr());
            if (xElement.toString().contains("Errors")) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH");
                response.IsSuccess = false;

                FlightOrderException exception = new FlightOrderException();
                exception.setPassenger(orderInfo.getCustomerName());
                FlightOrderInfoTickets orderInfoTickets = new FlightOrderInfoTickets();
                orderInfoTickets.setOrderId(orderInfo.getOrderId());
                List<FlightOrderInfoTickets> ticketsList = orderInfoTicketsService.selectFlightOrderInfoTicketsList(orderInfoTickets);
                if (orderInfo.getTripType().equals("ow")) {
                    if (ticketsList.size() > 1) {
                        if (ticketsList.get(1).getTripType().equals("rt") || ticketsList.get(1).getTripType().equals("ot")) {
                            for (int i = 0; i < 2; i++) {
                                exception.setFlightno(ticketsList.get(i).getFlight());
                                exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                                exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                                exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                                exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                                exception.setSourceWay(orderInfo.getSourceTypeId());
                                exception.setStatus("untreated");
                                exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                exception.setOrderType("reserve");
                                exception.setPnr(orderInfo.getPnr());
                                flightOrderExceptionService.insertFlightOrderException(exception);
                            }
                        } else {
                            exception.setFlightno(ticketsList.get(0).getFlight());
                            exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                            exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                            exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                            exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                            exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                            exception.setSourceWay(orderInfo.getSourceTypeId());
                            exception.setStatus("untreated");
                            exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                            exception.setOrderType("reserve");
                            exception.setPnr(orderInfo.getPnr());
                            flightOrderExceptionService.insertFlightOrderException(exception);
                        }
                    } else {
                        exception.setFlightno(ticketsList.get(0).getFlight());
                        exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                        exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                        exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                        exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                        exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                        exception.setSourceWay(orderInfo.getSourceTypeId());
                        exception.setStatus("untreated");
                        exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                        exception.setOrderType("reserve");
                        exception.setPnr(orderInfo.getPnr());
                        flightOrderExceptionService.insertFlightOrderException(exception);
                    }
                } else if (orderInfo.getTripType().equals("rt")) {
                    for (int i = 0; i < 2; i++) {
                        exception.setFlightno(ticketsList.get(i).getFlight());
                        exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                        exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                        exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                        exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                        exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                        exception.setSourceWay(orderInfo.getSourceTypeId());
                        exception.setStatus("untreated");
                        exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                        exception.setOrderType("reserve");
                        exception.setPnr(orderInfo.getPnr());
                        flightOrderExceptionService.insertFlightOrderException(exception);
                    }
                }
                orderInfo.setStatus(FlightOrderConstants.ticketingFail.getValue());
                orderInfoService.updateFlightOrderInfo(orderInfo);
                orderInfoTicketsService.updateFlightOrderInfoTicketsByOrderId(orderInfo.getOrderId(), FlightOrderConstants.ticketingFail.getValue());
                return response;
            }
            List<XElement> FlightSegmentList = xElement.element("AirResRet").element("FlightSegments").elements("FlightSegment");
            String goStatus = FlightSegmentList.get(0).getAttributeValue("Status");
            XElement noXElement = new XElement();
            if (FlightSegmentList.size() > 1) {
                String backStatus = FlightSegmentList.get(1).getAttributeValue("Status");
                if ("NO".equals(goStatus) && "NO".equals(backStatus)) {
                    noXElement = noComplement(orderInfo.getPnr(), ticketList);
                    if (noXElement.toString().contains("Errors")) {
                        response.ErrorCode = noXElement.element("Errors").element("Error").getAttributeValue("Code");
                        response.ErrorMsg = xElement.element("Errors").element("Error").getAttributeValue("ShortText");
                        response.IsSuccess = false;

                        FlightOrderException exception = new FlightOrderException();
                        exception.setPassenger(orderInfo.getCustomerName());
                        FlightOrderInfoTickets orderInfoTickets = new FlightOrderInfoTickets();
                        orderInfoTickets.setOrderId(orderInfo.getOrderId());
                        List<FlightOrderInfoTickets> ticketsList = orderInfoTicketsService.selectFlightOrderInfoTicketsList(orderInfoTickets);
                        if (orderInfo.getTripType().equals("ow")) {
                            if (ticketsList.size() > 1) {
                                if (ticketsList.get(1).getTripType().equals("rt") || ticketsList.get(1).getTripType().equals("ot")) {
                                    for (int i = 0; i < 2; i++) {
                                        exception.setFlightno(ticketsList.get(i).getFlight());
                                        exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                                        exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                                        exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                                        exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                        exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                                        exception.setSourceWay(orderInfo.getSourceTypeId());
                                        exception.setStatus("untreated");
                                        exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                        exception.setOrderType("reserve");
                                        exception.setPnr(orderInfo.getPnr());
                                        flightOrderExceptionService.insertFlightOrderException(exception);
                                    }
                                } else {
                                    exception.setFlightno(ticketsList.get(0).getFlight());
                                    exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                                    exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                                    exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                                    exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                    exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                                    exception.setSourceWay(orderInfo.getSourceTypeId());
                                    exception.setStatus("untreated");
                                    exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                    exception.setOrderType("reserve");
                                    exception.setPnr(orderInfo.getPnr());
                                    flightOrderExceptionService.insertFlightOrderException(exception);
                                }
                            } else {
                                exception.setFlightno(ticketsList.get(0).getFlight());
                                exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                                exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                                exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                                exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                                exception.setSourceWay(orderInfo.getSourceTypeId());
                                exception.setStatus("untreated");
                                exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                exception.setOrderType("reserve");
                                exception.setPnr(orderInfo.getPnr());
                                flightOrderExceptionService.insertFlightOrderException(exception);
                            }
                        } else if (orderInfo.getTripType().equals("rt")) {
                            for (int i = 0; i < 2; i++) {
                                exception.setFlightno(ticketsList.get(i).getFlight());
                                exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                                exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                                exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                                exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                                exception.setSourceWay(orderInfo.getSourceTypeId());
                                exception.setStatus("untreated");
                                exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                exception.setOrderType("reserve");
                                exception.setPnr(orderInfo.getPnr());
                                flightOrderExceptionService.insertFlightOrderException(exception);
                            }
                        }
                        orderInfo.setStatus(FlightOrderConstants.ticketingFail.getValue());
                        orderInfoService.updateFlightOrderInfo(orderInfo);
                        orderInfoTicketsService.updateFlightOrderInfoTicketsByOrderId(orderInfo.getOrderId(), FlightOrderConstants.ticketingFail.getValue());
                        return response;
                    }
                }
            } else {
                if ("NO".equals(goStatus)) {
                    noXElement = noComplement(orderInfo.getPnr(), ticketList);
                    if (noXElement.toString().contains("Errors")) {
                        response.ErrorCode = noXElement.element("Errors").element("Error").getAttributeValue("Code");
                        response.ErrorMsg = xElement.element("Errors").element("Error").getAttributeValue("ShortText");
                        response.IsSuccess = false;

                        FlightOrderException exception = new FlightOrderException();
                        exception.setPassenger(orderInfo.getCustomerName());
                        FlightOrderInfoTickets orderInfoTickets = new FlightOrderInfoTickets();
                        orderInfoTickets.setOrderId(orderInfo.getOrderId());
                        List<FlightOrderInfoTickets> ticketsList = orderInfoTicketsService.selectFlightOrderInfoTicketsList(orderInfoTickets);
                        if (orderInfo.getTripType().equals("ow")) {
                            if (ticketsList.size() > 1) {
                                if (ticketsList.get(1).getTripType().equals("rt") || ticketsList.get(1).getTripType().equals("ot")) {
                                    for (int i = 0; i < 2; i++) {
                                        exception.setFlightno(ticketsList.get(i).getFlight());
                                        exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                                        exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                                        exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                                        exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                        exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                                        exception.setSourceWay(orderInfo.getSourceTypeId());
                                        exception.setStatus("untreated");
                                        exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                        exception.setOrderType("reserve");
                                        exception.setPnr(orderInfo.getPnr());
                                        flightOrderExceptionService.insertFlightOrderException(exception);
                                    }
                                } else {
                                    exception.setFlightno(ticketsList.get(0).getFlight());
                                    exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                                    exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                                    exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                                    exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                    exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                                    exception.setSourceWay(orderInfo.getSourceTypeId());
                                    exception.setStatus("untreated");
                                    exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                    exception.setOrderType("reserve");
                                    exception.setPnr(orderInfo.getPnr());
                                    flightOrderExceptionService.insertFlightOrderException(exception);
                                }
                            } else {
                                exception.setFlightno(ticketsList.get(0).getFlight());
                                exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                                exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                                exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                                exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                                exception.setSourceWay(orderInfo.getSourceTypeId());
                                exception.setStatus("untreated");
                                exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                exception.setOrderType("reserve");
                                exception.setPnr(orderInfo.getPnr());
                                flightOrderExceptionService.insertFlightOrderException(exception);
                            }
                        } else if (orderInfo.getTripType().equals("rt")) {
                            for (int i = 0; i < 2; i++) {
                                exception.setFlightno(ticketsList.get(i).getFlight());
                                exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                                exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                                exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                                exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                exception.setExceptionInfo(xElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                                exception.setSourceWay(orderInfo.getSourceTypeId());
                                exception.setStatus("untreated");
                                exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                exception.setOrderType("reserve");
                                exception.setPnr(orderInfo.getPnr());
                                flightOrderExceptionService.insertFlightOrderException(exception);
                            }
                        }
                        orderInfo.setStatus(FlightOrderConstants.ticketingFail.getValue());
                        orderInfoService.updateFlightOrderInfo(orderInfo);
                        orderInfoTicketsService.updateFlightOrderInfoTicketsByOrderId(orderInfo.getOrderId(), FlightOrderConstants.ticketingFail.getValue());
                        return response;
                    }
                }
            }

            //记录支付信息


            //修改订单收款状态
            orderInfo.setGuestPymtStsId(FlightOrderConstants.payd.toString()); //已支付
            orderInfo.setStatus(FlightOrderConstants.noTravel.getValue());
            orderInfo.setIssueTime(new Date());

            //获取出票渠道信息
            //获取出票渠道主表信息
            FlightChannelRule channelRule = channelRuleService.selectFlightChannelInfo(ticketList.get(0).getAirliner());
            //获取出票渠道详细信息
            FlightInterface flightInterface = interfaceService.selectFlightInterfaceByAirCodeAndType(channelRule.getAirlinerId(), Long.valueOf(channelRule.getPeksourcetype()));

            if (flightInterface.getSourcetype() == Integer.parseInt(FlightOrderConstants.bsp.getValue())) {
                orderInfo.setTicketChannel(FlightOrderConstants.bsp.toString());
                orderInfoService.updateFlightOrderInfo(orderInfo);
                //直接走出票接口
                //出票，需要乘机人信息
                List<String> pasList = new ArrayList<>();
                StringBuffer buffer = null;//仓位
                for (FlightOrderInfoTickets infoTickets : ticketList) {
                    if (buffer == null) {
                        buffer = new StringBuffer();
                    } else {
                        buffer.append("+");
                    }
                    buffer.append(infoTickets.getCabin());

                    //乘客姓名
                    if (!pasList.contains(infoTickets.getGuestName())) {
                        pasList.add(infoTickets.getGuestName());
                    }
                }

                String cpMark = "";
                FlightAdjust flightAdjust = adjustService.getFlightAdjustByAirCodeAndCardId(ticketList.get(0).getAirliner(), customerR.getData().getCustCertificateNo());
                if (flightAdjust != null) {
                    String adjustCpMark = flightAdjust.getCpMark();
                    String[] split = adjustCpMark.split("\\|");
                    String spl = split[0];
                    cpMark = spl.substring(1);
                }

                //出票
                XElement outTicketElement = outTicket(orderInfo.getPnr(), cpMark, pasList, buffer.toString(), String.valueOf(calculationResponse.getAmount()), calculationResponse.getAmount(), calculationResponse.getFuelTax(), calculationResponse.getAirportTax());

                if (outTicketElement.toString().contains("Errors")) {
                    response.ErrorMsg = "出票失败，请联系人工处理！";
                    response.IsSuccess = false;
                    outticketLog.setLoginfo("出票失败，请联系人工处理！");
                    outticketLog.setCreateTime(new Date());
                    outticketLogService.insertFlightOutticketLog(outticketLog);

                    FlightOrderException exception = new FlightOrderException();
                    exception.setPassenger(orderInfo.getCustomerName());
                    FlightOrderInfoTickets orderInfoTickets = new FlightOrderInfoTickets();
                    orderInfoTickets.setOrderId(orderInfo.getOrderId());
                    List<FlightOrderInfoTickets> ticketsList = orderInfoTicketsService.selectFlightOrderInfoTicketsList(orderInfoTickets);
                    if (orderInfo.getTripType().equals("ow")) {
                        if (ticketsList.size() > 1) {
                            if (ticketsList.get(1).getTripType().equals("rt") || ticketsList.get(1).getTripType().equals("ot")) {
                                for (int i = 0; i < 2; i++) {
                                    exception.setFlightno(ticketsList.get(i).getFlight());
                                    exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                                    exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                                    exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                                    exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                    exception.setExceptionInfo(outTicketElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                                    exception.setSourceWay(orderInfo.getSourceTypeId());
                                    exception.setStatus("untreated");
                                    exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                    exception.setOrderType("reserve");
                                    exception.setPnr(orderInfo.getPnr());
                                    flightOrderExceptionService.insertFlightOrderException(exception);
                                }
                            } else {
                                exception.setFlightno(ticketsList.get(0).getFlight());
                                exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                                exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                                exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                                exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                exception.setExceptionInfo(outTicketElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                                exception.setSourceWay(orderInfo.getSourceTypeId());
                                exception.setStatus("untreated");
                                exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                exception.setOrderType("reserve");
                                exception.setPnr(orderInfo.getPnr());
                                flightOrderExceptionService.insertFlightOrderException(exception);
                            }
                        } else {
                            exception.setFlightno(ticketsList.get(0).getFlight());
                            exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                            exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                            exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                            exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                            exception.setExceptionInfo(outTicketElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                            exception.setSourceWay(orderInfo.getSourceTypeId());
                            exception.setStatus("untreated");
                            exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                            exception.setOrderType("reserve");
                            exception.setPnr(orderInfo.getPnr());
                            flightOrderExceptionService.insertFlightOrderException(exception);
                        }
                    } else if (orderInfo.getTripType().equals("rt")) {
                        for (int i = 0; i < 2; i++) {
                            exception.setFlightno(ticketsList.get(i).getFlight());
                            exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                            exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                            exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                            exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                            exception.setExceptionInfo(outTicketElement.element("Errors").element("Error").getAttributeValue("ShortTextZH"));
                            exception.setSourceWay(orderInfo.getSourceTypeId());
                            exception.setStatus("untreated");
                            exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                            exception.setOrderType("reserve");
                            exception.setPnr(orderInfo.getPnr());
                            flightOrderExceptionService.insertFlightOrderException(exception);
                        }
                    }
                    orderInfo.setStatus(FlightOrderConstants.ticketingFail.getValue());
                    orderInfoService.updateFlightOrderInfo(orderInfo);
                    orderInfoTicketsService.updateFlightOrderInfoTicketsByOrderId(orderInfo.getOrderId(), FlightOrderConstants.ticketingFail.getValue());
                    return response;
                }

                Map<String, String> msg = new HashMap<>();
                BigDecimal totalPrice = new BigDecimal(0);
                List<XElement> ticketItemInfo = outTicketElement.elements("TicketItemInfo");
                for (XElement ticketInfo : ticketItemInfo) {

                    //票号
                    String TicketNumber = ticketInfo.getAttributeValue("TicketNumber");
                    //金额
                    String TotalAmount = ticketInfo.getAttributeValue("TotalAmount");
                    //乘客姓名
                    String psName = xmlMapper.readValue(ticketInfo.element("PassengerName").element("Surname").toString(), String.class);
                    //状态
                    String TicketStatus = ticketInfo.element("FlightSegment").getAttributeValue("TicketStatus");

                    if (buffer == null) {
                        buffer = new StringBuffer();
                    } else {
                        buffer.append(",");
                    }
                    buffer.append(TicketNumber);

                    if ("OPEN FOR USE".equals(TicketStatus)) {
                        totalPrice = totalPrice.add(new BigDecimal(TotalAmount));
                        response.IsSuccess = true;
                        //反填票号
                        ticketList.forEach(item -> {
                            if (item.getGuestName().equals(psName)) {
                                item.setTicketNo(TicketNumber);
                                item.setStatus(FlightOrderConstants.ticketing.getValue());
                                orderInfoTicketsService.updateFlightOrderInfoTickets(item);
                            }
                        });

                        msg.put("旅客:" + psName, " 票号为:" + TicketNumber);
                        outticketLog.setLoginfo("该订单在领达出票成功！");
                        outticketLog.setCreateTime(new Date());
                        outticketLogService.insertFlightOutticketLog(outticketLog);
                    } else {
                        msg.put("旅客:" + psName, " 出票失败，请联系人工处理！");
                        outticketLog.setLoginfo("旅客:" + psName + " 出票失败，请联系人工处理！");
                        outticketLog.setCreateTime(new Date());
                        outticketLogService.insertFlightOutticketLog(outticketLog);

                        FlightOrderException exception = new FlightOrderException();
                        exception.setPassenger(psName);
                        FlightOrderInfoTickets orderInfoTickets = new FlightOrderInfoTickets();
                        orderInfoTickets.setOrderId(orderInfo.getOrderId());
                        List<FlightOrderInfoTickets> ticketsList = orderInfoTicketsService.selectFlightOrderInfoTicketsList(orderInfoTickets);
                        if (orderInfo.getTripType().equals("ow")) {
                            if (ticketsList.size() > 1) {
                                if (ticketsList.get(1).getTripType().equals("rt") || ticketsList.get(1).getTripType().equals("ot")) {
                                    for (int i = 0; i < 2; i++) {
                                        exception.setFlightno(ticketsList.get(i).getFlight());
                                        exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                                        exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                                        exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                                        exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                        exception.setExceptionInfo("旅客:" + psName + " 出票失败，请联系人工处理！");
                                        exception.setSourceWay("App");
                                        exception.setStatus("untreated");
                                        exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                        exception.setOrderType("reserve");
                                        exception.setPnr(orderInfo.getPnr());
                                        flightOrderExceptionService.insertFlightOrderException(exception);
                                    }
                                } else {
                                    exception.setFlightno(ticketsList.get(0).getFlight());
                                    exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                                    exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                                    exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                                    exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                    exception.setExceptionInfo("旅客:" + psName + " 出票失败，请联系人工处理！");
                                    exception.setSourceWay("App");
                                    exception.setStatus("untreated");
                                    exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                    exception.setOrderType("reserve");
                                    exception.setPnr(orderInfo.getPnr());
                                    flightOrderExceptionService.insertFlightOrderException(exception);
                                }
                            } else {
                                exception.setFlightno(ticketsList.get(0).getFlight());
                                exception.setFlightinfo(ticketsList.get(0).getOrgAirport() + ticketsList.get(0).getDstAirport());
                                exception.setDepartureTime(ticketsList.get(0).getDepartureTime());
                                exception.setArrivalTime(ticketsList.get(0).getArrivalTime());
                                exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                exception.setExceptionInfo("旅客:" + psName + " 出票失败，请联系人工处理！");
                                exception.setSourceWay("App");
                                exception.setStatus("untreated");
                                exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                exception.setOrderType("reserve");
                                exception.setPnr(orderInfo.getPnr());
                                flightOrderExceptionService.insertFlightOrderException(exception);
                            }
                        } else if (orderInfo.getTripType().equals("rt")) {
                            for (int i = 0; i < 2; i++) {
                                exception.setFlightno(ticketsList.get(i).getFlight());
                                exception.setFlightinfo(ticketsList.get(i).getOrgAirport() + ticketsList.get(i).getDstAirport());
                                exception.setDepartureTime(ticketsList.get(i).getDepartureTime());
                                exception.setArrivalTime(ticketsList.get(i).getArrivalTime());
                                exception.setOutticketType(EnumHelper.RequestType.LinkStar.toString());
                                exception.setExceptionInfo("旅客:" + psName + " 出票失败，请联系人工处理！");
                                exception.setSourceWay("App");
                                exception.setStatus("untreated");
                                exception.setOrderId(String.valueOf(orderInfo.getOrderId()));
                                exception.setOrderType("reserve");
                                exception.setPnr(orderInfo.getPnr());
                                flightOrderExceptionService.insertFlightOrderException(exception);
                            }
                        }
                        orderInfo.setStatus(FlightOrderConstants.ticketingFail.getValue());
                        orderInfoService.updateFlightOrderInfo(orderInfo);
                        orderInfoTicketsService.updateFlightOrderInfoTicketsByOrderId(orderInfo.getOrderId(), FlightOrderConstants.ticketingFail.getValue());
                    }
                }

                response.PayInfo.PayAmount = totalPrice;
                response.ErrorMsg = msg.toString();
                response.IsSuccess = true;
                //response.PayInfo.TradeId=builder.toString();
                //orderInfo.setTicketChannel(FlightOrderConstants.bsp.toString());
                XElement otaAirResRetByPnrId = getOTAAirResRetByPnrId(orderInfo.getPnr());
                String status = otaAirResRetByPnrId.element("AirResRet").element("FlightSegments").element("FlightSegment").getAttributeValue("Status");
                orderInfo.setActionCode(status);
                orderInfoService.updateFlightOrderInfo(orderInfo);
            } else if (flightInterface.getSourcetype() == Integer.parseInt(FlightOrderConstants.b2b.getValue())) {
                orderInfo.setTicketChannel(FlightOrderConstants.b2b.toString());
                //判断走那个接口支付。易宝、汇付天下
                MoAutoPayOutTicketRequest outTicketRequest = new MoAutoPayOutTicketRequest();
                outTicketRequest.AirCode = ticketList.get(0).getAirliner();
                outTicketRequest.PayAmount = orderInfo.getTicketAmount(); //总价
                outTicketRequest.Pnr = orderInfo.getPnr();
                outTicketRequest.OrderID = moRequest.OrderID;
                MoContacts moContacts = new MoContacts();
                moContacts.ContactMobile = "17710180782";
                moContacts.ContactName = "金色世纪";
                outTicketRequest.MoContacts = moContacts;
                //大编
                outTicketRequest.BigPnr = orderInfo.getBigpnr();
                //票价
                outTicketRequest.TicketAmount = new BigDecimal(calculationResponse.getAmount());
                //税费
                outTicketRequest.Tax = new BigDecimal(calculationResponse.getFuelTax()).add(new BigDecimal(calculationResponse.getAirportTax()));

                if (flightInterface.getOtherpath() == Integer.parseInt(FlightOrderConstants.yeePay.getValue())) {
                    //出票前校验
                    OutTicketCheckResponse checkResponse = yeePay.checkOutTicket(outTicketRequest);
                    checkResponse.setTicketSourceWay(Integer.parseInt(FlightOrderConstants.yeePay.getValue()));
                    if (checkResponse.isSuccess()) {
                        //交给消息队列去处理出票
                        ticketProducter.sendMessage("YeePayTicketQueue", JSON.toJSONString(checkResponse));
                        //orderInfo.setTicketChannel(FlightOrderConstants.b2b.toString());
                        XElement otaAirResRetByPnrId = getOTAAirResRetByPnrId(orderInfo.getPnr());
                        String status = otaAirResRetByPnrId.element("AirResRet").element("FlightSegments").element("FlightSegment").getAttributeValue("Status");
                        orderInfo.setActionCode(status);
                        orderInfoService.updateFlightOrderInfo(orderInfo);
                        outticketLog.setLoginfo("该订单在领达出票成功！");
                        outticketLog.setCreateTime(new Date());
                        outticketLogService.insertFlightOutticketLog(outticketLog);
                    } else {
                        response.ErrorMsg = checkResponse.getMsg();
                        outticketLog.setLoginfo("该订单在领达出票失败！");
                        outticketLog.setCreateTime(new Date());
                        outticketLogService.insertFlightOutticketLog(outticketLog);
                        orderInfo.setStatus(FlightOrderConstants.ticketingFail.getValue());
                        orderInfoService.updateFlightOrderInfo(orderInfo);
                        orderInfoTicketsService.updateFlightOrderInfoTicketsByOrderId(orderInfo.getOrderId(), FlightOrderConstants.ticketingFail.getValue());
                        return response;
                    }

                } else if (flightInterface.getOtherpath() == Integer.parseInt(FlightOrderConstants.huiFu.getValue())) {
                    OutTicketCheckResponse checkResponse = huifu.checkOutTicket(outTicketRequest);
                    if (checkResponse.isSuccess()) {
                        //交给消息队列去处理出票
                        ticketProducter.sendMessage("HuifuTicketQueue", JSON.toJSONString(outTicketRequest));
                        //orderInfo.setTicketChannel(FlightOrderConstants.b2b.toString());
                        XElement otaAirResRetByPnrId = getOTAAirResRetByPnrId(orderInfo.getPnr());
                        String status = otaAirResRetByPnrId.element("AirResRet").element("FlightSegments").element("FlightSegment").getAttributeValue("Status");
                        orderInfo.setActionCode(status);
                        orderInfoService.updateFlightOrderInfo(orderInfo);
                        outticketLog.setLoginfo("该订单在领达出票成功！");
                        outticketLog.setCreateTime(new Date());
                        outticketLogService.insertFlightOutticketLog(outticketLog);
                    } else {
                        response.ErrorMsg = checkResponse.getMsg();
                        outticketLog.setLoginfo("该订单在领达出票失败！");
                        outticketLog.setCreateTime(new Date());
                        outticketLogService.insertFlightOutticketLog(outticketLog);
                        orderInfo.setStatus(FlightOrderConstants.ticketingFail.getValue());
                        orderInfoService.updateFlightOrderInfo(orderInfo);
                        orderInfoTicketsService.updateFlightOrderInfoTicketsByOrderId(orderInfo.getOrderId(), FlightOrderConstants.ticketingFail.getValue());
                        return response;
                    }
                }
                orderInfo.setStatus(FlightOrderConstants.ticketing.getValue());
                orderInfoService.updateFlightOrderInfo(orderInfo);
                orderInfoTicketsService.updateFlightOrderInfoTicketsByOrderId(orderInfo.getOrderId(), FlightOrderConstants.ticketing.getValue());
            }

        } catch (Exception e) {
            e.printStackTrace();
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            response.IsSuccess = false;
            return response;
        }
        return response;

    }


    /**
     * 申请退票
     *
     * @param moRequest
     * @return
     */
    @Override
    public MoOrderRefundResponse _OrderRefund(MoOrderRefundRequest moRequest) {
        MoOrderRefundResponse response = new MoOrderRefundResponse();
        try {
            //申请退票
            CalculateRefundRes refundRes = autoRefundTicket(moRequest.OrderID, moRequest.ListMoPassenger);
            response.IsSuccess = refundRes.isSuccess();
            response.ErrorMsg = refundRes.getMsg();
            response.ErrorCode = refundRes.getCode();
            response.RefundAmount = new BigDecimal(refundRes.getNetRefund());
            response.RefundFee = new BigDecimal(refundRes.getAmount());
        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            return response;
        }

        return response;
    }

    /**
     * 申请退票CRM
     * @param moRequest
     * @return
     */
    public MoOrderRefundResponse _OrderRefundCRM(MoOrderRefundRequest moRequest) {
        MoOrderRefundResponse response = new MoOrderRefundResponse();
        try {
            //申请退票
            CalculateRefundRes refundRes = autoRefundTicketCRM(moRequest.OrderID, moRequest.ListMoPassenger);
            response.IsSuccess = refundRes.isSuccess();
            response.ErrorMsg = refundRes.getMsg();
            response.ErrorCode = refundRes.getCode();
            response.RefundAmount = new BigDecimal(refundRes.getNetRefund());
            response.RefundFee = new BigDecimal(refundRes.getAmount());
            response.refundNumber = refundRes.getRefundNumber();
        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            return response;
        }

        return response;
    }

    public MoOrderRefundResponse _OrderRefunds(Long orderID, List<String> ticketNo) {
        MoOrderRefundResponse response = new MoOrderRefundResponse();
        try {
            //申请退票
            CalculateRefundRes refundRes = autoRefundTickets(orderID, ticketNo);
            response.IsSuccess = refundRes.isSuccess();
            response.ErrorMsg = refundRes.getMsg();
            response.ErrorCode = refundRes.getCode();
            response.RefundAmount = new BigDecimal(refundRes.getNetRefund());
            response.RefundFee = new BigDecimal(refundRes.getAmount());
        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            return response;
        }

        return response;
    }

    public MoOrderRefundResponse _OrderRefundsCRM(List<String> ticketNo) {
        MoOrderRefundResponse response = new MoOrderRefundResponse();
        try {
            //申请退票
            CalculateRefundRes refundRes = autoRefundTicketsCRM(ticketNo);
            response.IsSuccess = refundRes.isSuccess();
            response.ErrorMsg = refundRes.getMsg();
            response.ErrorCode = refundRes.getCode();
            response.RefundAmount = new BigDecimal(refundRes.getNetRefund());
            response.RefundFee = new BigDecimal(refundRes.getAmount());
            response.refundNumber = refundRes.getRefundNumber();
        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            return response;
        }

        return response;
    }

    /**
     * 改签申请退票
     *
     * @param moRequest
     * @return
     */
    public MoOrderRefundResponse _changeOrderRefund(MoOrderRefundRequest moRequest) {
        MoOrderRefundResponse response = new MoOrderRefundResponse();
        try {
            //申请退票
            CalculateRefundRes refundRes = changeRefundTicket(moRequest.OrderID, moRequest.ticketNo);
            response.IsSuccess = refundRes.isSuccess();
            response.ErrorMsg = refundRes.getMsg();
            response.ErrorCode = refundRes.getCode();
            response.RefundAmount = new BigDecimal(refundRes.getNetRefund());
            response.RefundFee = new BigDecimal(refundRes.getAmount());
        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            return response;
        }

        return response;
    }

    /**
     * CRM改签申请退票
     *
     * @param moRequest
     * @return
     */
    public MoOrderRefundResponse _changeOrderRefundCRM(MoOrderRefundRequest moRequest) {
        MoOrderRefundResponse response = new MoOrderRefundResponse();
        try {
            //申请退票
            CalculateRefundRes refundRes = changeRefundTicketCRM(moRequest.OrderID, moRequest.ticketNo);
            response.IsSuccess = refundRes.isSuccess();
            response.ErrorMsg = refundRes.getMsg();
            response.ErrorCode = refundRes.getCode();
            response.RefundAmount = new BigDecimal(refundRes.getNetRefund());
            response.RefundFee = new BigDecimal(refundRes.getAmount());
            response.refundNumber = refundRes.getRefundNumber();
        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            return response;
        }

        return response;
    }

    public static boolean isNumeric(String str){
        for(int i = str.length(); --i >= 0;) {
            if(!Character.isDigit(str.charAt(i))){
                return false;
            }
        }
        return true;
    }

    /**
     * 申请改签
     *
     * @param moRequest
     * @return
     */
    @Override
    public synchronized MoOrderChangeResponse _OrderChange(MoOrderChangeRequest moRequest) {
        MoOrderChangeResponse response = new MoOrderChangeResponse();
        try {
            XElement xElement = ticketChangesFlight(moRequest);
            XmlMapper xmlMapper = new XmlMapper();

            if (xElement.toString().contains("Errors")) {
                Object code = xmlMapper.readValue(xElement.element("Errors").element("Error").getAttributeValue("Code"), Object.class);
                String shortText = xmlMapper.readValue(xElement.element("Errors").element("Error").getAttributeValue("ShortText"), String.class);
                response.ErrorMsg = shortText;
                response.ErrorCode = String.valueOf(code);
                response.IsSuccess = false;
                return response;
            }
            XElement ticketItemInfo = xElement.element("TicketItemInfo");
            JSONObject xml = XML.toJSONObject(String.valueOf(ticketItemInfo));
            String jsonStr = xml.toString();

            com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(jsonStr);
            com.alibaba.fastjson.JSONObject ticketItemInfoJsonObject = jsonObject.getJSONObject("TicketItemInfo");

            Map<String, Object> ticketItemInfoMap = new HashMap<>();

            //循环转换
            for (Map.Entry<String, Object> entry : ticketItemInfoJsonObject.entrySet()) {
                ticketItemInfoMap.put(entry.getKey(), entry.getValue());
            }
            //改签后的票号
            String ticketNumber = ticketItemInfoMap.get("TicketNumber").toString();
            //支付的金额
            String TotalAmount = ticketItemInfoMap.get("TotalAmount").toString();

            //改签信息，写入数据表中
            //如果用户改签后想退票，之前生成的pnr已经不能使用了，需要改签之前新生成的pnr才可以操作
            String newOrderId = moRequest.newOrderId;
            FlightOrderChangeTickets changeTicketsById = changeTicketsService.selectFlightOrderChangeTicketsById(Long.valueOf(newOrderId));
            XElement otaAirResRetByPnrId = getOTAAirResRetByPnrId(changeTicketsById.getPnr());
            String status = otaAirResRetByPnrId.element("AirResRet").element("FlightSegments").element("FlightSegment").getAttributeValue("Status");
            changeTicketsById.setTicketNo(ticketNumber);
            changeTicketsById.setChangeFee(new BigDecimal(TotalAmount));
            changeTicketsById.setActionCode(status);
            changeTicketsById.setStatus(FlightOrderConstants.ticketing.getValue());
            changeTicketsService.updateFlightOrderChangeTickets(changeTicketsById);

            response.ApplicationId = ticketNumber;
            response.PayAmount = new BigDecimal(TotalAmount);
            response.IsSuccess = true;
        } catch (Exception e) {
            response.ErrorCode = String.valueOf(EnumHelper.ReturnCode.系统异常代码.getValue());
            response.ErrorMsg = EnumHelper.ReturnCode.系统异常代码.toString();
            response.IsSuccess = false;
            e.printStackTrace();
        }
        return response;
    }


    /**
     * 客票变更搜索(改签航班查询)
     */
    public MoFlightSearchResponse changeSearchFlight(ChangeFlightRequest request) {
        MoFlightSearchResponse response = new MoFlightSearchResponse();
        try {

            //获取订单详细信息
            FlightOrderInfoTickets flightOrderInfoTickets = orderInfoTicketsService.getFlightOrderInfoByTicketNo(request.getTicketNo());
            String guestType = flightOrderInfoTickets.getGuestType(); //乘机人类型
            String guestName = flightOrderInfoTickets.getGuestName(); //乘机人姓名
            String date = request.getDepartureTime(); //起飞时间
            String newDate = date.substring(0, 10);
            String[] split = newDate.split("-");
            StringBuilder builder = new StringBuilder();
            for (String s : split) {
                builder.append(s);
            }

            boolean isInfant = false; //是否婴儿
            if (guestType.equals(EnumHelper.PassengerType.婴儿.toString())) {
                isInfant = true;
            }

            String strRequestData = String.format("<OTA_AirTicketReShopRQ>\n" +
                            "    <POS>\n" +
                            "        <Source>\n" +
                            "            <PseudoCityCode>%s</PseudoCityCode>\n" +
                            "            <airlinecode>%s</airlinecode>\n" +
                            "            <CityCode>BJS</CityCode>\n" +
                            "            <iatacode>%s</iatacode>\n" +
                            "        </Source>\n" +
                            "    </POS>\n" +
                            "    <FlightSegments>\n" +
                            "        <FlightSegment>\n" +
                            "            <departure LocationCode=\"%s\" />\n" +
                            "            <arrival LocationCode=\"%s\" />\n" +
                            "            <equipment AirEquipType=\"%s\" />\n" +
                            "            <marketingCarrier Code=\"%s\" />\n" +
                            "            <operationCarrier Code=\"%s\" />\n" +
                            "            <flightno>%s</flightno>\n" +
                            "            <departureTime>%s</departureTime>\n" +
                            "            <type>NORMAL</type>\n" +
                            "            <cabin>%s</cabin>\n" +
                            "            <changed>true</changed>\n" +
                            "            <actionCode>HK</actionCode>\n" +
                            "            <TicketNumber_Before>%s</TicketNumber_Before>\n" +
                            "            <IsInfant>%s</IsInfant>\n" +
                            "            <PassName>%s</PassName>\n" +
                            "            <PassID>P1</PassID>\n" +
                            "            <PassCount>1</PassCount>\n" +
                            "            <InvoluntaryIdentifier>false</InvoluntaryIdentifier>\n" +
                            "            <querydepdate>%s</querydepdate>\n" +
                            "        </FlightSegment>\n" +
                            "    </FlightSegments>\n" +
                            "</OTA_AirTicketReShopRQ>", OFFICE, request.getAirline(), IATACODE, request.getOrgAirport(), request.getDstAirport(),
                    request.getAirEquipType(), request.getAirline(), request.getAirline(), request.getFlightNo(), request.getDepartureTime(), request.getCabin(),
                    request.getTicketNo(), isInfant, guestName, builder.toString());

            String strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketReShop", strRequestData);
            XElement root = XElement.loadXml(strResponseData);

            if (root.toString().contains("Errors")) {
                String code = root.element("Errors").element("Error").getAttributeValue("Code");
                String msg = root.element("Errors").element("Error").getAttributeValue("ShortTextZH");
                String text = root.element("Errors").element("Error").element("Trace").getAttributeValue("Text");
                String errMsg = msg + text;

                response.ErrorCode = code;
                response.ErrorMsg = errMsg;
                return response;
            }


            //将xml转为json
            JSONObject xml = XML.toJSONObject(strResponseData);
            String jsonStr = xml.toString(4);
            ChangeSearchResponse changeSearchResponse = JSON.parseObject(jsonStr, ChangeSearchResponse.class);

            //解析航班信息
            List<ChangeAvOpt> avOpt = changeSearchResponse.OTA_AirTicketReShopRS.Result.AvJourneys.AvJourney.AvOpt;
            //舱位等级
            List<ChangePFare> pFare = changeSearchResponse.OTA_AirTicketReShopRS.Result.PFares.PFare;
//            List<NFare> nFare = flightRes.FareInterface.Output.Result.FlightShopResult.NFares.NFare;
            //价格
            List<ChangePS> ps = changeSearchResponse.OTA_AirTicketReShopRS.Result.PSn.PS;
            for (ChangeAvOpt changeAvOpt : avOpt) {
                ChangeFlt flt = changeAvOpt.Flt;
                MoFlightInfo info = new MoFlightInfo();
                info.Airline = flt.airline;
                info.FlightNo = flt.fltNo;
                info.DstAirport = flt.arr;
                info.DstAirportName = getAirPortNameByRirPortCode(flt.arr);
                info.OrgAirport = flt.dep;
                info.OrgAirportName = getAirPortNameByRirPortCode(flt.dep);
                info.TPM = Integer.parseInt(flt.tpm);
                info.StopCount = Integer.parseInt(flt.stop);
                info.PlaneStyle = flt.dev; //机型
                String deptm = flt.deptm;
                String dateTime = request.getDepartureTime();
                dateTime = dateTime.substring(0, 10);
                String deptmDate = dateTime + " " + insertStr(deptm, 2, ":");
                info.DepDate = convertStrToDate(deptmDate);
                String arrtm = flt.arrtm;
                String arrtmDate = dateTime + " " + insertStr(arrtm, 2, ":");
                info.ArrDate = convertStrToDate(arrtmDate);


                //计算飞行时长
                long diff = info.DepDate.getTime() - info.ArrDate.getTime();
                long diffMinutes = diff / (60 * 1000) % 60;
                long diffHours = diff / (60 * 60 * 1000) % 24;

                String flightTimes = "";
                if (diffHours == 0) {
                    flightTimes = diffMinutes + "分钟";
                } else if (diffMinutes == 0) {
                    flightTimes = diffHours + "小时";
                } else if (diffHours != 0 && diffMinutes != 0) {
                    flightTimes = diffHours + "小时" + diffMinutes + "分钟";
                }

                info.flightTimes = flightTimes.replace("-", "");


                //航站楼
                ChangeTerm term = flt.Term;
                info.ArrTerm = term.arr;

                //获取返回的仓位信息
                List<ChangeClass> aClass = flt.Class;
                for (ChangeClass changeClass : aClass) {
                    String av = changeClass.av;
                    //仓位
                    MoCabinInfo cinfo = new MoCabinInfo();
                    cinfo.Cabin = changeClass.name;
                    if ("A".equals(av)) {
                        cinfo.CabinLeftDesc = "座位充足";
                    } else {
                        cinfo.CabinLeftDesc = String.valueOf(Integer.parseInt(split[1]));
                    }

                    //餐食
                    String meal = flt.meal;
                    if (!StringHelper.isNullOrEmpty(meal)) {
                        String mealSub = meal.substring(0, 1);
                        String mealSubTwo = meal.substring(1);
                        if (mealSubTwo != null && !mealSubTwo.equals("")) {
                            cinfo.Meal = meal(mealSubTwo);
                        } else {
                            cinfo.Meal = meal(mealSub);
                        }
                    }else {
                        cinfo.Meal = "无";
                    }

                    //获取价格
                    ps.forEach(item -> {
                        String disAmt = item.CabinFares.CabinFare.amount;
                        item.Routs.forEach(rout -> {
                            String rt = rout.Rout.carr + rout.Rout.fltNo + rout.Rout.bkClass;
                            String pt = flt.airline + flt.fltNo + cinfo.Cabin;
                            if (rt.equals(pt)) {
                                cinfo.CallCenterAmountInfo.OrgTicketAmount = new BigDecimal(disAmt);
                                cinfo.CallCenterAmountInfo.TicketAmount = new BigDecimal(item.FCs.FC.YFares.yFareAmount);
                                String cabinLevelId = item.FCs.FC.FareBind.fareRPH;
                                ChangePFare tmpPFare = pFare.stream().filter(cItem->cItem.rPH.equals(cabinLevelId)).findFirst().orElse(null);
                                if (tmpPFare!=null)
                                {
                                    cinfo.BaseCabin = tmpPFare.cbClass;
                                    if (tmpPFare.cbClass.toUpperCase().equals("Y"))
                                    {
                                        cinfo.BaseCabinName = "经济舱";
                                    }
                                    if (tmpPFare.cbClass.toUpperCase().equals("C"))
                                    {
                                        cinfo.BaseCabinName = "公务舱";
                                    }
                                    if (tmpPFare.cbClass.toUpperCase().equals("F"))
                                    {
                                        cinfo.BaseCabinName = "头等舱";
                                    }
                                }
                            }
                        });
                    });
                    info.ListCabinInfo.add(cinfo);
                }
                response.ListGoFlightInfo.add(info);
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.ErrorCode = String.valueOf(EnumHelper.ReturnCode.系统异常代码.getValue());
            response.ErrorMsg = EnumHelper.ReturnCode.系统异常代码.toString();
        }
        response.channelType = 14;
        return response;

    }

    /**
     * 国内按pnr变更费计算
     */
    public ReIssuePriceResponse airReIssuePrice(AirReIssuePriceRequest request) {

        ReIssuePriceResponse response = new ReIssuePriceResponse();

        //判断是否是婴儿
        boolean isInfant = false;
        String ticketNo = request.getTicketNo();
        FlightOrderInfoTickets tickets = orderInfoTicketsService.getFlightOrderInfoByTicketNo(ticketNo);
        String guestType = tickets.getGuestType();
        if (guestType.equals(EnumHelper.PassengerType.婴儿.toString())) {
            isInfant = true;
        }
        String guestName = tickets.getGuestName();

        String requestData = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                        "<OTA_AirReIssuePriceRQ>\n" +
                        "    <POS>\n" +
                        "        <Source>\n" +
                        "            <airlinecode>%s</airlinecode>\n" +
                        "            <iatacode>%s</iatacode>\n" +
                        "            <CityCode>BJS</CityCode>\n" +
                        "            <PseudoCityCode>%s</PseudoCityCode>\n" +
                        "        </Source>\n" +
                        "    </POS>\n" +
                        "    <ReIssueinfos>\n" +
                        "        <ReIssueinfo>\n" +
                        "            <FlightSegments>\n" +
                        "                <FlightSegment>\n" +
                        "                    <departure LocationCode=\"%s\" />\n" +
                        "                    <arrival LocationCode=\"%s\" />\n" +
                        "                    <equipment AirEquipType=\"%s\" />\n" +
                        "                    <marketingCarrier Code=\"%s\" />\n" +
                        "                    <operationCarrier Code=\"%s\" />\n" +
                        "                    <departureTime>%s</departureTime>\n" +
                        "                    <arrivalTime>%s</arrivalTime>\n" +
                        "                    <type>NORMAL</type>\n" +
                        "                    <flightno>%s</flightno>\n" +
                        "                    <cabin>%s</cabin>\n" +
                        "                    <actionCode>HK</actionCode>\n" +
                        "                </FlightSegment>\n" +
                        "            </FlightSegments>\n" +
                        "            <TicketNumber_Before>%s</TicketNumber_Before>\n" +
                        "            <IsInfant>%s</IsInfant>\n" +
                        "            <PassName>%s</PassName>\n" +
                        "            <InvoluntaryIdentifier>false</InvoluntaryIdentifier>\n" +
                        "            <BookingReferenceID ID=\"%s\" ID_Context=\"PNR\" />\n" +
                        "        </ReIssueinfo>\n" +
                        "    </ReIssueinfos>\n" +
                        "</OTA_AirReIssuePriceRQ>", tickets.getAirliner(), IATACODE, OFFICE, tickets.getOrgAirport(), tickets.getDstAirport(),
                request.getEquipment(), tickets.getAirliner(), tickets.getAirliner(), request.getDepartureTime(), request.getArrivalTime(), request.getFlightNo(), request.getCabin(), request.getTicketNo(), isInfant, guestName, request.getOrderId());

        try {
            //发送请求
            String strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirReIssuePrice", requestData);
            XElement root = XElement.loadXml(strResponseData);

            //解析数据
            XElement ticketChangerResponse = root.element("TicketChangerResponse");
            if (ticketChangerResponse.toString().contains("Errors")) {
                String code = ticketChangerResponse.element("Errors").element("Error").getAttributeValue("Code");
                String msg = ticketChangerResponse.element("Errors").element("Error").getAttributeValue("ShortTextZH");
                String text = ticketChangerResponse.element("Errors").element("Error").element("Trace").getAttributeValue("Text");
                String errMsg = msg + text;
                response.setSuccess(false);
                response.setMsg(errMsg);
                return response;
            }

            List<XElement> reissueResult = ticketChangerResponse.elements("reissueResult");
            XElement xElement = reissueResult.get(0);
            XmlMapper xmlMapper = new XmlMapper();
            //String ei = xmlMapper.readValue(xElement.element("ei").toString(), String.class); //描述
            String changedFee = xmlMapper.readValue(xElement.element("changedFee").toString(), String.class); //计算得到的改期费
            String farediff = xmlMapper.readValue(xElement.element("farediff").toString(), String.class); //实际收取的票价差。缺省为 0
            String taxdiff = xmlMapper.readValue(xElement.element("taxdiff").toString(), String.class); //实际收取的税差。
            //String Totalfare = xmlMapper.readValue(xElement.element("Totalfare").toString(), String.class);
            //String exchangeType = xmlMapper.readValue(xElement.element("exchangeType").toString(), String.class);//1：出新票；0：不出新票
            //String ticketFare = xmlMapper.readValue(xElement.element("ticketFare").toString(), String.class);
            //String oi = xmlMapper.readValue(xElement.element("oi").toString(), String.class); //票号
            //String[] ticketOi = oi.split("#");
            //String ticket = ticketOi[0];
            response.setSuccess(true);
            response.setPayPrice(farediff);
            response.setChangedFee(changedFee);
            response.setTaxdiff(taxdiff);

        } catch (Exception e) {
            e.printStackTrace();
            response.setSuccess(true);
            response.setMsg(EnumHelper.ReturnCode.系统异常代码.toString());
        }

        return response;

    }


    /**
     * 国内公布价运价查询
     *
     * @param vo
     * @return
     */
    public FlightPublishPriceResVo publishPrice(FlightPublishPriceReqVo vo) {

        FlightPublishPriceResVo response = new FlightPublishPriceResVo();

        String PassengerType = "ADT";
        if (vo.getPassengerType() == EnumHelper.PassengerType.成人.getValue()) {
            PassengerType = "ADT";
        }
        if (vo.getPassengerType() == EnumHelper.PassengerType.儿童.getValue()) {
            PassengerType = "CHD";
        }
        if (vo.getPassengerType() == EnumHelper.PassengerType.婴儿.getValue()) {
            PassengerType = "INF";
        }

        String strReqData = String.format("<OTA_AirFareDisplayRQ>\n" +
                "    <POS>\n" +
                "        <Source PseudoCityCode=\"%s\" />\n" +
                "    </POS>\n" +
                "    <OriginDestinationInformation>\n" +
                "        <OriginDestinationOptions>\n" +
                "            <OriginDestinationOption RPH=\"1\">\n" +
                "                <FlightSegment DepartureDateTime=\"%s\">\n" +
                "                    <Equipment AirEquipType=\"\" />\n" +
                "                    <DepartureAirport LocationCode=\"%s\" />\n" +
                "                    <ArrivalAirport LocationCode=\"%s\" />\n" +
                "                    <MarketingAirline Code=\"%s\" />\n" +
                "                </FlightSegment>\n" +
                "            </OriginDestinationOption>\n" +
                "        </OriginDestinationOptions>\n" +
                "    </OriginDestinationInformation>\n" +
                "    <TravelerInfoSummary GroupInd=\"false\">\n" +
                "        <AirTravelerAvail>\n" +
                "            <PassengerTypeQuantity Code=\"%s\" />\n" +
                "        </AirTravelerAvail>\n" +
                "    </TravelerInfoSummary>\n" +
                "</OTA_AirFareDisplayRQ>", OFFICE, vo.getDepDate(), vo.getDstAirport(), vo.getOrgAirport(), vo.getAirlineCode(), PassengerType);


        try {

            String strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirFareDisplay/D", strReqData);


            XElement root = XElement.loadXml(strResponseData);

            List<XElement> airItineraryPricingInfo = root.elements("AirItineraryPricingInfo");

            if (root.toString().contains("Errors")) {
                XElement errorEle = root.element("Errors").element("Error");
                response.code = errorEle.getAttributeValue("Code");
                response.msg = errorEle.getAttributeValue("ShortTextZH");
                return response;
            }

            if (root.toString().contains("Warnings")) {
                XElement WarningEle = root.element("Warnings").element("Warning");
                response.code = WarningEle.getAttributeValue("Code");
                response.msg = WarningEle.getAttributeValue("ShortText");
                return response;
            }

            response.TPM = root.getAttributeValue("TPM");


            //将xml转为json
            JSONObject xml = XML.toJSONObject(airItineraryPricingInfo.toString());
            String jsonStr = xml.toString(4);

            OTA_AirFareDisplayRSRes displayRSResVo = JSON.parseObject(jsonStr, OTA_AirFareDisplayRSRes.class);

            response.rsRes = displayRSResVo;

        } catch (Exception e) {
            response.code = EnumHelper.ReturnCode.系统异常代码.toString();
            response.msg = EnumHelper.ReturnCode.系统异常代码.toString();
            return response;
        }

        return response;
    }


    /**
     * 转换月份
     *
     * @param month
     * @return
     */
    private String convertMonth(String month) {
        String str = "";
        switch (month) {
            case "01":
                str = "JAN";
                break;
            case "02":
                str = "FEB";
                break;
            case "03":
                str = "MAR";
                break;
            case "04":
                str = "APR";
                break;
            case "05":
                str = "MAY";
                break;
            case "06":
                str = "JUN";
                break;
            case "07":
                str = "JUL";
                break;
            case "08":
                str = "AUG";
                break;
            case "09":
                str = "SEP";
                break;
            case "10":
                str = "OCT";
                break;
            case "11":
                str = "NOV";
                break;
            case "12":
                str = "DEC";
                break;
        }

        return str;
    }


    /**
     * 请求日期处理，将月份转为对应的英文
     *
     * @param source
     * @return
     */
    private String splicingData(String source) {
        //分割
        String[] split = source.split("-");
        List<String> list = new ArrayList<>();
        for (int i = 0; i < split.length; i++) {
            if (i == 0) {
                String str = split[i];
                list.add(str.substring(2, str.length()));
            }
            if (i == 1) {
                list.add(convertMonth(split[i]));
            }
            if (i == 2) {
                list.add(split[i]);
            }

        }

        //逆序排列
        Collections.reverse(list);
        String result = "";
        for (String str : list) {
            result += str;
        }

        return result;
    }

    /**
     * 航班查询返回时间处理
     *
     * @return
     */
    private Date convertStrToDate(String str) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date parse = null;
        try {
            parse = format.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parse;
    }

    /**
     * 在指定位置插入字符
     *
     * @param str      源字符串
     * @param position 要插入的位置
     * @param newStr   新的字符串
     * @return
     */
    private String insertStr(String str, int position, String newStr) {
        StringBuffer buffer = new StringBuffer(str);
        buffer.insert(position, newStr);
        return buffer.toString();
    }


    /**
     * 获取仓位等级（航班查询，往返使用）
     *
     * @param elementList
     * @param fareRPH
     * @return
     */
    private String getPFares(List<XElement> elementList, String fareRPH) {
        String result = "";
        try {
            XmlMapper xmlMapper = new XmlMapper();
            for (int i = 0; i < elementList.size(); i++) {
                String rph = xmlMapper.readValue(elementList.get(i).element("RPH").toString(), String.class);
                if (Objects.equals(fareRPH, rph)) {
                    result = xmlMapper.readValue(elementList.get(i).element("cbClass").toString(), String.class);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 获取舱位等级
     *
     * @param cabinLevelId
     * @param cinfo
     * @param pFare
     * @param nFare
     */
    private void getCabinLevel(String cabinLevelId, MoCabinInfo cinfo, List<PFare> pFare, List<NFare> nFare) {
        if (pFare != null && pFare.size() > 0) {
            PFare tmpPFare = pFare.stream().filter(pItem -> pItem.RPH.equals(cabinLevelId)).findFirst().orElse(null);
            if (tmpPFare != null) {
                cinfo.BaseCabin = tmpPFare.cbClass;
                if (tmpPFare.cbClass.toUpperCase().equals("Y")) {
                    cinfo.BaseCabinName = "经济舱";
                }
                if (tmpPFare.cbClass.toUpperCase().equals("C")) {
                    cinfo.BaseCabinName = "公务舱";
                }
                if (tmpPFare.cbClass.toUpperCase().equals("F")) {
                    cinfo.BaseCabinName = "头等舱";
                }
            }
        }
        if (nFare != null && nFare.size() > 0) {
            NFare tmpNFare = nFare.stream().filter(nItem -> nItem.RPH.equals(cabinLevelId)).findFirst().orElse(null);
            if (tmpNFare != null) {
                cinfo.BaseCabin = tmpNFare.cbClass;
                if (tmpNFare.cbClass.toUpperCase().equals("Y")) {
                    cinfo.BaseCabinName = "经济舱";
                }
                if (tmpNFare.cbClass.toUpperCase().equals("C")) {
                    cinfo.BaseCabinName = "公务舱";
                }
                if (tmpNFare.cbClass.toUpperCase().equals("F")) {
                    cinfo.BaseCabinName = "头等舱";
                }
            }
        }
    }


    /**
     * 根据航班获取航班出发、抵达地(航班查询，往返使用)
     *
     * @param moFlightInfoList
     * @param str
     * @return
     */
    private Map<String, Object> getFlightList(List<MoFlightInfo> moFlightInfoList, String str) {
        Map<String, Object> map = new HashMap<>();
        for (MoFlightInfo moFlightInfo : moFlightInfoList) {
            if (str.equals(moFlightInfo.Airline + moFlightInfo.FlightNo)) {
                map.put("DstAirport", moFlightInfo.DstAirport);
                map.put("OrgAirport", moFlightInfo.OrgAirport);
                break;
            }
        }
        return map;
    }

    /**
     * 获取往返信息
     *
     * @param avOptList
     * @param date
     * @return
     * @throws JsonProcessingException
     */
    private List<MoFlightInfo> getMoFlightInfo(List<RAvOpt> avOptList, List<RPS> rpsList, String date, RPFares fares, RPFares rpFares, String flights, boolean hasChildren) throws JsonProcessingException {
        List<MoFlightInfo> infoList = new ArrayList<>();

        for (int i = 0; i < avOptList.size(); i++) {

            RFlt flt = avOptList.get(i).Flt;
            //共享航班
            if (flt.codeshare != null) {
                continue;
            }
            MoFlightInfo info = new MoFlightInfo();
            info.Airline = flt.airline; //航司
            String fltNo = flt.fltNo; //航班号
            info.FlightNo = fltNo;
            String DstAirport = flt.arr;
            info.DstAirport = DstAirport;
            //抵达机场名称
            info.DstAirportName= getAirPortNameByRirPortCode(DstAirport);
            String OrgAirport = flt.dep;
            info.OrgAirport = OrgAirport;
            //出发机场名称
            info.OrgAirportName=getAirPortNameByRirPortCode(OrgAirport);
            info.TPM = Integer.parseInt(flt.tpm);
            info.StopCount = Integer.parseInt(flt.stop);
            info.PlaneStyle = flt.dev; //机型

            String deptm = flt.deptm;
            String deptmDate = date + " " + insertStr(deptm, 2, ":");
            if (flt.depad == 0) {
                info.DepDate = convertStrToDate(deptmDate);
            } else {
                Date time = convertStrToDate(deptmDate);
                info.DepDate = DateCalcUtils.addDay(time, flt.depad);
            }

            String arrtm = flt.arrtm;
            String arrtmDate = date + " " + insertStr(arrtm, 2, ":");
            if (flt.arrad == 0) {
                info.ArrDate = convertStrToDate(arrtmDate);
            } else {
                Date time = convertStrToDate(arrtmDate);
                info.ArrDate = DateCalcUtils.addDay(time, flt.arrad);
            }

            //计算飞行时长
            long diff = info.DepDate.getTime() - info.ArrDate.getTime();
            long diffMinutes = diff / (60 * 1000) % 60;
            long diffHours = diff / (60 * 60 * 1000) % 24;

            String flightTimes = "";
            if (diffHours == 0) {
                flightTimes = diffMinutes + "分钟";
            } else if (diffMinutes == 0) {
                flightTimes = diffHours + "小时";
            } else if (diffHours != 0 && diffMinutes != 0) {
                flightTimes = diffHours + "小时" + diffMinutes + "分钟";
            }

            info.flightTimes = flightTimes.replace("-", "");

            info.depad = flt.depad;
            info.arrad = flt.arrad;

            //航站楼
            if (flt.term != null) {
                RTerm term = flt.term;
                info.ArrTerm = term.arr;
                info.DepTerm = term.dep;
            }

            //经停信息
            if (flt.stopOvers != null) {
                info.stopPlace = flt.stopOvers.stopInfo.stopCity;
                info.stopTime = flt.stopOvers.stopInfo.stopTime;
            }

            //获取返回的仓位信息
            String classStr = flt.classStr;
            String[] cabins = classStr.split(";");
            Set<String> refundSet = new HashSet<>();
            Set<String> changeSet = new HashSet<>();
            for (String cabin : cabins) {
                AtomicBoolean foundCabin = new AtomicBoolean(false);
                //仓位
                MoCabinInfo cinfo = new MoCabinInfo();
                //餐食
                String meal = flt.meal;
                if (!StringHelper.isNullOrEmpty(meal)) {
                    String mealSub = meal.substring(0, 1);
                    String mealSubTwo = meal.substring(1);
                    if (mealSubTwo != null && !mealSubTwo.equals("")) {
                        cinfo.Meal = meal(mealSubTwo);
                    } else {
                        cinfo.Meal = meal(mealSub);
                    }
                }else {
                    cinfo.Meal = "无";
                }
                String[] split = cabin.split(":");
                cinfo.Cabin = split[0];
                if ("A".equals(split[1])) {
                    cinfo.CabinLeftDesc = "座位充足";
                } else {
                    cinfo.CabinLeftDesc = String.valueOf(Integer.parseInt(split[1]));
                }
                rpsList.forEach(item -> {
                    //燃油和基建
                    String[] cnTax = getTaxInfo(item.Taxes.Tax.get(0).taxComponent.get(0));
                    String[] yqTax = getTaxInfo(item.Taxes.Tax.get(1).taxComponent.get(0));
                    if (item.passengerType.equals("AD")) {
                        info.AirportTax = new BigDecimal(cnTax[0]);
                        info.FuelTax = new BigDecimal(yqTax[0]);
                    } else if (item.passengerType.equals("CH")) {
                        info.ChildAirportTax = new BigDecimal(cnTax[0]);
                        info.ChildFuelTax = new BigDecimal(yqTax[0]);
                    } else if (item.passengerType.equals("IN")) {
                        info.InfantAirportTax = new BigDecimal(cnTax[0]);
                        info.InfantFuelTax = new BigDecimal(yqTax[0]);
                    }

                    String disAmt = null;
                    if (item.FCs.FC.size() > 1) {
                        if (flights.equals("go")) {
                            disAmt = item.FCs.FC.get(0).disAmt;
                        } else if (flights.equals("back")) {
                            disAmt = item.FCs.FC.get(1).disAmt;
                        }
                    } else {
                        disAmt = item.FCs.FC.get(0).disAmt;
                    }

                    //获取出来的价格是往返组合价格，且是相同航司的相同 仓位。（除2得出单程）
                    //BigDecimal price = new BigDecimal(item.disAmt).divide(new BigDecimal(2));
                    BigDecimal finalDisAmt = new BigDecimal(disAmt);
                    item.Routs.forEach(rRouts -> {
                        String[] flightNoAndCabin = rRouts.routStr.split(";");
                        String flight = null;
                        Boolean codeShare = false;
                        if (flt.codeshare != null) {
                            flight = flt.codeshare.airline + flt.codeshare.fltno + ":" + cinfo.Cabin;
                            codeShare = true;
                            info.IsCodeShare = codeShare;
                            info.Carrier = flt.codeshare.airline + flt.codeshare.fltno;
                        } else {
                            flight = flt.airline + flt.fltNo + ":" + cinfo.Cabin;
                            info.IsCodeShare = codeShare;
                        }
                        if (item.FCs.FC.size() > 1) {
                            if (flightNoAndCabin[0].equals(flight) || (flt.codeshare != null && flightNoAndCabin[0].indexOf(flt.codeshare.fltno) != -1)) {
                                foundCabin.set(true);
                                cinfo.CallCenterAmountInfo.OrgTicketAmount = finalDisAmt;
                                cinfo.CallCenterAmountInfo.TicketAmount = new BigDecimal(item.FCs.FC.get(0).YFares.yFareAmount.get(0));

                                /*if (cinfo.CallCenterAmountInfo.OrgTicketAmount != null && cinfo.CallCenterAmountInfo.TicketAmount != null && cinfo.CallCenterAmountInfo.TicketAmount.intValue() > 0) {
                                    BigDecimal multiply = null;
                                    BigDecimal divide = cinfo.CallCenterAmountInfo.OrgTicketAmount.divide(cinfo.CallCenterAmountInfo.TicketAmount, 2, BigDecimal.ROUND_HALF_UP);
                                    if (divide.compareTo(new BigDecimal(1)) > 0)
                                        multiply = new BigDecimal(1).multiply(new BigDecimal(100));
                                    else
                                        multiply = divide.multiply(new BigDecimal(100));
                                    cinfo.CallCenterAmountInfo.DisCountRate = multiply;
                                }*/
                                if (hasChildren) {
                                    BigDecimal divide = cinfo.CallCenterAmountInfo.OrgTicketAmount.divide(cinfo.CallCenterAmountInfo.TicketAmount, 2, BigDecimal.ROUND_HALF_UP);
                                    if (divide.compareTo(new BigDecimal(0.5)) <= 0) {
                                        cinfo.CallCenterAmountInfo.OrgChdTicketAmount = finalDisAmt;
                                    } else if (divide.compareTo(new BigDecimal(0.5)) > 0) {
                                        cinfo.CallCenterAmountInfo.OrgChdTicketAmount = finalDisAmt.divide(new BigDecimal(2));
                                    }
                                }
                                cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                                String cabinLevelId = item.FCs.FC.get(0).FareBind.fareRPH;
                                if (fares != null) {
                                    RPFare tmpPFare = fares.PFare.stream().filter(pItem -> pItem.RPH.equals(cabinLevelId)).findFirst().orElse(null);
                                    if (tmpPFare != null) {
                                        cinfo.BaseCabin = tmpPFare.cbClass;
                                        if (tmpPFare.cbClass.toUpperCase().equals("Y")) {
                                            cinfo.BaseCabinName = "经济舱";
                                        }
                                        if (tmpPFare.cbClass.toUpperCase().equals("C")) {
                                            cinfo.BaseCabinName = "公务舱";
                                        }
                                        if (tmpPFare.cbClass.toUpperCase().equals("F")) {
                                            cinfo.BaseCabinName = "头等舱";
                                        }
                                    } else {
                                        if (rpFares != null) {
                                            RPFare nPFare = rpFares.NFare.stream().filter(pItem -> pItem.RPH.equals(cabinLevelId)).findFirst().orElse(null);
                                            if (nPFare != null) {
                                                cinfo.BaseCabin = nPFare.cbClass;
                                                if (nPFare.cbClass.toUpperCase().equals("Y")) {
                                                    cinfo.BaseCabinName = "经济舱";
                                                }
                                                if (nPFare.cbClass.toUpperCase().equals("C")) {
                                                    cinfo.BaseCabinName = "公务舱";
                                                }
                                                if (nPFare.cbClass.toUpperCase().equals("F")) {
                                                    cinfo.BaseCabinName = "头等舱";
                                                }
                                            }
                                        }
                                    }
                                } else if (rpFares != null) {
                                    RPFare nPFare = rpFares.NFare.stream().filter(pItem -> pItem.RPH.equals(cabinLevelId)).findFirst().orElse(null);
                                    if (nPFare != null) {
                                        cinfo.BaseCabin = nPFare.cbClass;
                                        if (nPFare.cbClass.toUpperCase().equals("Y")) {
                                            cinfo.BaseCabinName = "经济舱";
                                        }
                                        if (nPFare.cbClass.toUpperCase().equals("C")) {
                                            cinfo.BaseCabinName = "公务舱";
                                        }
                                        if (nPFare.cbClass.toUpperCase().equals("F")) {
                                            cinfo.BaseCabinName = "头等舱";
                                        }
                                    }
                                }
                                cinfo.Cabin = cinfo.Cabin.substring(0, 1);
                            } else if (flightNoAndCabin[1].equals(flight) || (flt.codeshare != null && flightNoAndCabin[1].indexOf(flt.codeshare.fltno) != -1)) {
                                foundCabin.set(true);
                                cinfo.CallCenterAmountInfo.OrgTicketAmount = finalDisAmt;
                                cinfo.CallCenterAmountInfo.TicketAmount = new BigDecimal(item.FCs.FC.get(1).YFares.yFareAmount.get(0));

                                /*if (cinfo.CallCenterAmountInfo.OrgTicketAmount != null && cinfo.CallCenterAmountInfo.TicketAmount != null && cinfo.CallCenterAmountInfo.TicketAmount.intValue() > 0) {
                                    BigDecimal multiply = null;
                                    BigDecimal divide = cinfo.CallCenterAmountInfo.OrgTicketAmount.divide(cinfo.CallCenterAmountInfo.TicketAmount, 2, BigDecimal.ROUND_HALF_UP);
                                    if (divide.compareTo(new BigDecimal(1)) > 0)
                                        multiply = new BigDecimal(1).multiply(new BigDecimal(100));
                                    else
                                        multiply = divide.multiply(new BigDecimal(100));
                                    cinfo.CallCenterAmountInfo.DisCountRate = multiply;
                                }*/
                                if (hasChildren) {
                                    BigDecimal divide = cinfo.CallCenterAmountInfo.OrgTicketAmount.divide(cinfo.CallCenterAmountInfo.TicketAmount, 2, BigDecimal.ROUND_HALF_UP);
                                    if (divide.compareTo(new BigDecimal(0.5)) <= 0) {
                                        cinfo.CallCenterAmountInfo.OrgChdTicketAmount = finalDisAmt;
                                    } else if (divide.compareTo(new BigDecimal(0.5)) > 0) {
                                        cinfo.CallCenterAmountInfo.OrgChdTicketAmount = finalDisAmt.divide(new BigDecimal(2));
                                    }
                                }
                                cinfo.CabinRule.Baggage = item.FCs.FC.get(1).SecInfo.get(0).Baggage;
                                String cabinLevelId = item.FCs.FC.get(1).FareBind.fareRPH;
                                if (fares != null) {
                                    RPFare tmpPFare = fares.PFare.stream().filter(pItem -> pItem.RPH.equals(cabinLevelId)).findFirst().orElse(null);
                                    if (tmpPFare != null) {
                                        cinfo.BaseCabin = tmpPFare.cbClass;
                                        if (tmpPFare.cbClass.toUpperCase().equals("Y")) {
                                            cinfo.BaseCabinName = "经济舱";
                                        }
                                        if (tmpPFare.cbClass.toUpperCase().equals("C")) {
                                            cinfo.BaseCabinName = "公务舱";
                                        }
                                        if (tmpPFare.cbClass.toUpperCase().equals("F")) {
                                            cinfo.BaseCabinName = "头等舱";
                                        }
                                    } else {
                                        if (rpFares != null) {
                                            RPFare nPFare = rpFares.NFare.stream().filter(pItem -> pItem.RPH.equals(cabinLevelId)).findFirst().orElse(null);
                                            if (nPFare != null) {
                                                cinfo.BaseCabin = nPFare.cbClass;
                                                if (nPFare.cbClass.toUpperCase().equals("Y")) {
                                                    cinfo.BaseCabinName = "经济舱";
                                                }
                                                if (nPFare.cbClass.toUpperCase().equals("C")) {
                                                    cinfo.BaseCabinName = "公务舱";
                                                }
                                                if (nPFare.cbClass.toUpperCase().equals("F")) {
                                                    cinfo.BaseCabinName = "头等舱";
                                                }
                                            }
                                        }
                                    }
                                } else if (rpFares != null) {
                                    RPFare nPFare = rpFares.NFare.stream().filter(pItem -> pItem.RPH.equals(cabinLevelId)).findFirst().orElse(null);
                                    if (nPFare != null) {
                                        cinfo.BaseCabin = nPFare.cbClass;
                                        if (nPFare.cbClass.toUpperCase().equals("Y")) {
                                            cinfo.BaseCabinName = "经济舱";
                                        }
                                        if (nPFare.cbClass.toUpperCase().equals("C")) {
                                            cinfo.BaseCabinName = "公务舱";
                                        }
                                        if (nPFare.cbClass.toUpperCase().equals("F")) {
                                            cinfo.BaseCabinName = "头等舱";
                                        }
                                    }
                                }
                                cinfo.Cabin = cinfo.Cabin.substring(0, 1);
                            }
                        } else {
                            foundCabin.set(true);
                            cinfo.CallCenterAmountInfo.OrgTicketAmount = finalDisAmt;
                            cinfo.CallCenterAmountInfo.TicketAmount = new BigDecimal(item.FCs.FC.get(0).YFares.yFareAmount.get(0));

                            /*if (cinfo.CallCenterAmountInfo.OrgTicketAmount != null && cinfo.CallCenterAmountInfo.TicketAmount != null && cinfo.CallCenterAmountInfo.TicketAmount.intValue() > 0) {
                                BigDecimal multiply = null;
                                BigDecimal divide = cinfo.CallCenterAmountInfo.OrgTicketAmount.divide(cinfo.CallCenterAmountInfo.TicketAmount, 2, BigDecimal.ROUND_HALF_UP);
                                if (divide.compareTo(new BigDecimal(1)) == 0)
                                    multiply = new BigDecimal(1).multiply(new BigDecimal(100));
                                else
                                    multiply = divide.multiply(new BigDecimal(100));
                                cinfo.CallCenterAmountInfo.DisCountRate = multiply;
                            }*/
                            if (hasChildren) {
                                BigDecimal divide = cinfo.CallCenterAmountInfo.OrgTicketAmount.divide(cinfo.CallCenterAmountInfo.TicketAmount, 2, BigDecimal.ROUND_HALF_UP);
                                if (divide.compareTo(new BigDecimal(0.5)) <= 0) {
                                    cinfo.CallCenterAmountInfo.OrgChdTicketAmount = finalDisAmt;
                                } else if (divide.compareTo(new BigDecimal(0.5)) > 0) {
                                    cinfo.CallCenterAmountInfo.OrgChdTicketAmount = finalDisAmt.divide(new BigDecimal(2));
                                }
                            }
                            cinfo.CabinRule.Baggage = item.FCs.FC.get(0).SecInfo.get(0).Baggage;
                            String cabinLevelId = item.FCs.FC.get(0).FareBind.fareRPH;
                            if (fares != null) {
                                RPFare tmpPFare = fares.PFare.stream().filter(pItem -> pItem.RPH.equals(cabinLevelId)).findFirst().orElse(null);
                                if (tmpPFare != null) {
                                    cinfo.BaseCabin = tmpPFare.cbClass;
                                    if (tmpPFare.cbClass.toUpperCase().equals("Y")) {
                                        cinfo.BaseCabinName = "经济舱";
                                    }
                                    if (tmpPFare.cbClass.toUpperCase().equals("C")) {
                                        cinfo.BaseCabinName = "公务舱";
                                    }
                                    if (tmpPFare.cbClass.toUpperCase().equals("F")) {
                                        cinfo.BaseCabinName = "头等舱";
                                    }
                                } else {
                                    if (rpFares != null) {
                                        RPFare nPFare = rpFares.NFare.stream().filter(pItem -> pItem.RPH.equals(cabinLevelId)).findFirst().orElse(null);
                                        if (nPFare != null) {
                                            cinfo.BaseCabin = nPFare.cbClass;
                                            if (nPFare.cbClass.toUpperCase().equals("Y")) {
                                                cinfo.BaseCabinName = "经济舱";
                                            }
                                            if (nPFare.cbClass.toUpperCase().equals("C")) {
                                                cinfo.BaseCabinName = "公务舱";
                                            }
                                            if (nPFare.cbClass.toUpperCase().equals("F")) {
                                                cinfo.BaseCabinName = "头等舱";
                                            }
                                        }
                                    }
                                }
                            } else if (rpFares != null) {
                                RPFare nPFare = rpFares.NFare.stream().filter(pItem -> pItem.RPH.equals(cabinLevelId)).findFirst().orElse(null);
                                if (nPFare != null) {
                                    cinfo.BaseCabin = nPFare.cbClass;
                                    if (nPFare.cbClass.toUpperCase().equals("Y")) {
                                        cinfo.BaseCabinName = "经济舱";
                                    }
                                    if (nPFare.cbClass.toUpperCase().equals("C")) {
                                        cinfo.BaseCabinName = "公务舱";
                                    }
                                    if (nPFare.cbClass.toUpperCase().equals("F")) {
                                        cinfo.BaseCabinName = "头等舱";
                                    }
                                }
                            }
                            cinfo.Cabin = cinfo.Cabin.substring(0, 1);
                        }
                    });

                    List<String> refundRph = null;
                    List<String> changeRph = null;
                    if (item.FCs.FC.size() > 1) {
                        if (item.FCs.FC.get(1).RefundDetailRph != null && item.FCs.FC.get(1).ReissueDetailRph != null) {
                            refundRph = item.FCs.FC.get(1).RefundDetailRph;
                            changeRph = item.FCs.FC.get(1).ReissueDetailRph;
                        } else {
                            refundRph = item.FCs.FC.get(0).RefundDetailRph;
                            changeRph = item.FCs.FC.get(0).ReissueDetailRph;
                        }
                    } else {
                        refundRph = item.FCs.FC.get(0).RefundDetailRph;
                        changeRph = item.FCs.FC.get(0).ReissueDetailRph;
                    }

                    if (cinfo.CabinRule.refundRph.size() == 0) {
                        if (refundRph.size() > 0) {
                            if (refundSet.add(info.FlightNo + cinfo.Cabin + refundRph))
                                cinfo.CabinRule.refundRph.addAll(refundRph);
                        }
                    }
                    if (cinfo.CabinRule.changeRph.size() == 0) {
                        if (changeRph.size() > 0) {
                            if (changeSet.add(info.FlightNo + cinfo.Cabin + changeRph))
                                cinfo.CabinRule.changeRph.addAll(changeRph);
                        }
                    }
                });
                if (StringHelper.isNullOrEmpty(cinfo.BaseCabin))
                    continue;
                if (foundCabin.get())
                {
                    info.ListCabinInfo.add(cinfo);
                }
            }
            if (info.ListCabinInfo.size() > 0)
                infoList.add(info);
        }

        return infoList;
    }

    /**
     * 实时仓位查询
     *
     * @param flightSegment
     * @return
     */
    private List<MoFlightInfo> getRealTimeFlight(XElement flightSegment) throws ParseException {

        List<MoFlightInfo> infoList = new ArrayList<>();

        MoFlightInfo info = new MoFlightInfo();

        info.LegNum = Integer.parseInt(flightSegment.getAttributeValue("SegmentID"));

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String deptTiem = flightSegment.getAttributeValue("DepartureDateTime").replace("T", " ");
        String arrTiem = flightSegment.getAttributeValue("ArrivalDateTime").replace("T", " ");

        info.DepDate = format.parse(deptTiem);
        info.ArrDate = format.parse(arrTiem);
        info.StopCount = Integer.parseInt(flightSegment.getAttributeValue("StopQuantity"));
        info.FlightNo = flightSegment.getAttributeValue("FlightNumber");
        info.IsCodeShare = Boolean.valueOf(flightSegment.getAttributeValue("CodeshareInd")); //是否共享航班
        info.PaxSegmentRefID = flightSegment.getAttributeValue("SegmentID");

        //出发、抵达
        XElement departureAirport = flightSegment.element("DepartureAirport");
        info.ArrTerm = departureAirport.getAttributeValue("Terminal");
        info.OrgAirport = departureAirport.getAttributeValue("LocationCode");

        XElement arrivalAirport = flightSegment.element("ArrivalAirport");
        info.DstAirport = arrivalAirport.getAttributeValue("LocationCode");
        info.DepTerm = arrivalAirport.getAttributeValue("Terminal");

        XElement marketingAirline = flightSegment.element("MarketingAirline");
        info.Airline = marketingAirline.getAttributeValue("Code");


        XElement equipment = flightSegment.element("Equipment");
        info.PlaneStyle = equipment.getAttributeValue("AirEquipType"); //机型

        //仓位
        List<XElement> bookingClassAvail = flightSegment.elements("BookingClassAvail");
        for (int j = 0; j < bookingClassAvail.size(); j++) {
            MoCabinInfo cabinInfo = new MoCabinInfo();
            cabinInfo.Cabin = bookingClassAvail.get(j).getAttributeValue("ResBookDesigCode");
            String count = bookingClassAvail.get(j).getAttributeValue("ResBookDesigQuantity");
            if ("A".equals(count)) {
                cabinInfo.CabinLeft = 10;
            } else {
                cabinInfo.CabinLeft = Integer.parseInt(count);
            }
            info.ListCabinInfo.add(cabinInfo);
        }

        infoList.add(info);

        return infoList;
    }


    /**
     * 预定PNR
     *
     * @param moRequest
     * @return
     */
    private String createPNR(MoCreateOrderRequest moRequest) {
        String str = String.format(
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                        "<OTA_AirBookRQ>\n" +
                        "    <POS>\n" +
                        "        <Source PseudoCityCode=\"%s\" />\n" +
                        "    </POS>\n" +
                        "    <AirItinerary>\n" +
                        "        <OriginDestinationOptions>\n" +
                        "            <OriginDestinationOption>\n", OFFICE);


        //航班信息
        if (moRequest.ListGoSegment.size() > 0) {
            if (moRequest.ListGoSegment.size() == 2) {
                String flightNo = moRequest.ListGoSegment.get(0).FlightNo;
                String newFlightNo = flightNo.substring(2);
                str = str + String.format("\n" +
                                "                <FlightSegment RPH=\"1\" DepartureDateTime=\"%s\" ArrivalDateTime=\"%s\" CodeshareInd=\"false\" FlightNumber=\"%s\" Status=\"NN\" SegmentType=\"NORMAL\">\n" +
                                "                    <DepartureAirport LocationCode=\"%s\" />\n" +
                                "                    <ArrivalAirport LocationCode=\"%s\" />\n" +
                                "                    <Equipment AirEquipType=\"%s\" />\n" +
                                "                    <MarketingAirline Code=\"%s\" />\n" +
                                "                    <BookingClassAvail ResBookDesigCode=\"%s\" />\n" +
                                "                </FlightSegment>\n", date(moRequest.ListGoSegment.get(0).DepDate, "yyyy-MM-dd HH:mm:ss"), date(moRequest.ListGoSegment.get(0).ArrDate, "yyyy-MM-dd HH:mm:ss"), newFlightNo,
                        moRequest.ListGoSegment.get(0).OrgAirport, moRequest.ListGoSegment.get(0).DstAirport, moRequest.ListGoSegment.get(0).PlaneStyle,
                        moRequest.ListGoSegment.get(0).Airline, moRequest.ListGoSegment.get(0).Cabin.substring(0, 1));

                String backFlightNo = moRequest.ListGoSegment.get(1).FlightNo;
                String backNewFlightNo = backFlightNo.substring(2);
                str = str + String.format("\n" +
                                "                <FlightSegment RPH=\"2\" DepartureDateTime=\"%s\" ArrivalDateTime=\"%s\" CodeshareInd=\"false\" FlightNumber=\"%s\" Status=\"NN\" SegmentType=\"NORMAL\">\n" +
                                "                    <DepartureAirport LocationCode=\"%s\" />\n" +
                                "                    <ArrivalAirport LocationCode=\"%s\" />\n" +
                                "                    <Equipment AirEquipType=\"%s\" />\n" +
                                "                    <MarketingAirline Code=\"%s\" />\n" +
                                "                    <BookingClassAvail ResBookDesigCode=\"%s\" />\n" +
                                "                </FlightSegment>\n", date(moRequest.ListGoSegment.get(1).DepDate, "yyyy-MM-dd HH:mm:ss"), date(moRequest.ListGoSegment.get(1).ArrDate, "yyyy-MM-dd HH:mm:ss"), backNewFlightNo,
                        moRequest.ListGoSegment.get(1).OrgAirport, moRequest.ListGoSegment.get(1).DstAirport, moRequest.ListGoSegment.get(1).PlaneStyle,
                        moRequest.ListGoSegment.get(1).Airline, moRequest.ListGoSegment.get(1).Cabin.substring(0, 1));
            } else {
                String flightNo = moRequest.ListGoSegment.get(0).FlightNo;
                String newFlightNo = flightNo.substring(2);
                str = str + String.format("\n" +
                                "                <FlightSegment RPH=\"1\" DepartureDateTime=\"%s\" ArrivalDateTime=\"%s\" CodeshareInd=\"false\" FlightNumber=\"%s\" Status=\"NN\" SegmentType=\"NORMAL\">\n" +
                                "                    <DepartureAirport LocationCode=\"%s\" />\n" +
                                "                    <ArrivalAirport LocationCode=\"%s\" />\n" +
                                "                    <Equipment AirEquipType=\"%s\" />\n" +
                                "                    <MarketingAirline Code=\"%s\" />\n" +
                                "                    <BookingClassAvail ResBookDesigCode=\"%s\" />\n" +
                                "                </FlightSegment>\n", date(moRequest.ListGoSegment.get(0).DepDate, "yyyy-MM-dd HH:mm:ss"), date(moRequest.ListGoSegment.get(0).ArrDate, "yyyy-MM-dd HH:mm:ss"), newFlightNo,
                        moRequest.ListGoSegment.get(0).OrgAirport, moRequest.ListGoSegment.get(0).DstAirport, moRequest.ListGoSegment.get(0).PlaneStyle,
                        moRequest.ListGoSegment.get(0).Airline, moRequest.ListGoSegment.get(0).Cabin.substring(0, 1));
            }
        }

        if (moRequest.ListBackSegment.size() > 0) {
            String flightNo = moRequest.ListBackSegment.get(0).FlightNo;
            String backFlightNo = flightNo.substring(2);
            str = str + String.format("\n" +
                            "                <FlightSegment RPH=\"2\" DepartureDateTime=\"%s\" ArrivalDateTime=\"%s\" CodeshareInd=\"false\" FlightNumber=\"%s\" Status=\"NN\" SegmentType=\"NORMAL\">\n" +
                            "                    <DepartureAirport LocationCode=\"%s\" />\n" +
                            "                    <ArrivalAirport LocationCode=\"%s\" />\n" +
                            "                    <Equipment AirEquipType=\"%s\" />\n" +
                            "                    <MarketingAirline Code=\"%s\" />\n" +
                            "                    <BookingClassAvail ResBookDesigCode=\"%s\" />\n" +
                            "                </FlightSegment>\n", date(moRequest.ListBackSegment.get(0).DepDate, "yyyy-MM-dd HH:mm:ss"), date(moRequest.ListBackSegment.get(0).ArrDate, "yyyy-MM-dd HH:mm:ss"), backFlightNo,
                    moRequest.ListBackSegment.get(0).OrgAirport, moRequest.ListBackSegment.get(0).DstAirport, moRequest.ListBackSegment.get(0).PlaneStyle,
                    moRequest.ListBackSegment.get(0).Airline, moRequest.ListBackSegment.get(0).Cabin.substring(0, 1));
        }

        str = str + String.format("\n" +
                "           </OriginDestinationOption>\n" +
                "        </OriginDestinationOptions>\n" +
                "    </AirItinerary>\n" +
                "    <TravelerInfo>\n");


        long count = moRequest.ListMoPassenger.stream().filter(item -> {
            return item.PassengerType == 3;
        }).count();

        List<MoPassenger> adt_chd = new ArrayList<>();
        List<MoPassenger> inf = new ArrayList<>();
        for (MoPassenger moPassenger : moRequest.ListMoPassenger) {
            if (moPassenger.PassengerType == EnumHelper.PassengerType.成人.getValue() || moPassenger.PassengerType == EnumHelper.PassengerType.儿童.getValue())
                adt_chd.add(moPassenger);
            if (moPassenger.PassengerType == EnumHelper.PassengerType.婴儿.getValue())
                inf.add(moPassenger);
        }

        for (int i = 0; i < adt_chd.size(); i++) {
            String PassengerType = "ADT";
            String cardType = "NI";
            if (moRequest.ListMoPassenger.get(i).PassengerType == EnumHelper.PassengerType.成人.getValue()) {
                PassengerType = "ADT";
            }
            if (moRequest.ListMoPassenger.get(i).PassengerType == EnumHelper.PassengerType.儿童.getValue()) {
                PassengerType = "CHD";
            }
            /*if (moRequest.ListMoPassenger.get(i).PassengerType == EnumHelper.PassengerType.婴儿.getValue()) {
                PassengerType = "INF";
            }*/

            if (moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.居民身份证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.港澳台居民居住证.getValue()) {
                cardType = "NI";
            } else if (moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.护照.getValue()) {
                cardType = "PP";
            } else if (moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.港澳通行证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.大陆居民来往台湾通行证.getValue() ||
                    moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.军官证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.文职干部证.getValue() ||
                    moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.义务兵证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.士官证.getValue() ||
                    moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.文职人员证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.职工证.getValue() ||
                    moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.武警警官证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.武警士兵证.getValue() ||
                    moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.海员证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.港澳居民来往内地通行证.getValue() ||
                    moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.台湾居民来往大陆通行证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.外交部签发的驻华外交人员证.getValue() ||
                    moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.外国人永久居留证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.出生医学证明.getValue() ||
                    moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.户口簿.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.学生证.getValue() ||
                    moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.户口所在地公安机关出具的身份证明.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.民航局规定的其他有效乘机身份证件.getValue()){
                cardType = "ID";
            } else {
                cardType = "UU";
            }

            if (cardType.equals("PP")) {
                if (PassengerType.equals("ADT")) {
                    if (inf.size() > 0) {
                        str += String.format("<AirTraveler BirthDate=\"%s\" PassengerTypeCode=\"INF\">\n" +
                                        "            <PersonName LanguageType=\"ZH\">\n" +
                                        "                <Surname>%s</Surname>\n" +
                                        "            </PersonName>\n" +
                                        "            <PersonName LanguageType=\"EN\">\n" +
                                        "                <Surname>%s</Surname>\n" +
                                        "            </PersonName>\n" +
                                        "            <PassengerTypeQuantity Age=\"%s\" />\n" +
                                        "            <TravelerRefNumber RPH=\"%s\" />\n" +
                                        "            <FlightSegmentRPHs>\n", dateProcessing(inf.get(0).Birthday), inf.get(0).PassengerName,
                                inf.get(0).englishSurname + "/" + inf.get(0).englishName, inf.get(0).age, (adt_chd.size() + i + 1));
                        for (int j = 0; j < moRequest.ListGoSegment.size(); j++) {
                            str += String.format("<FlightSegmentRPH>%s</FlightSegmentRPH>", (j + 1));
                        }
                        if (moRequest.ListBackSegment != null && moRequest.ListBackSegment.size() > 0) {
                            for (MoSegment moSegment : moRequest.ListBackSegment) {
                                str += String.format("<FlightSegmentRPH>%s</FlightSegmentRPH>", (moRequest.ListGoSegment.size() + 1));
                            }
                        }
                        str += String.format("</FlightSegmentRPHs>\n" +
                                "        </AirTraveler>\n");
                        str += String.format("<AirTraveler PassengerTypeCode=\"%s\" Gender=\"%s\">\n" +
                                        "    <PersonName LanguageType=\"EN\">\n" +
                                        "        <Surname>%s</Surname>\n" +
                                        "    </PersonName>\n" +
                                        "    <Document DocType=\"PP\" DocTypeDetail=\"P\" DocID=\"%s\" DocHolderNationality=\"%s\"\n" +
                                        "DocHolderInd=\"%s\" DocIssueCountry=\"%s\" BirthDate=\"%s\" Gender=\"%s\" ExpireDate=\"%s\" RPH=\"%s\">\n" +
                                        "        <DocHolderFormattedName>\n" +
                                        "            <GivenName>%s</GivenName>\n" +
                                        "            <Surname>%s</Surname>\n" +
                                        "        </DocHolderFormattedName>\n" +
                                        "    </Document>\n" +
                                        "    <TravelerRefNumber RPH=\"%s\" InfantTravelerRPH=\"%s\"/>\n" +
                                        "<FlightSegmentRPHs>\n", PassengerType, moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", moRequest.ListMoPassenger.get(i).englishSurname + "/" + moRequest.ListMoPassenger.get(i).englishName,
                                moRequest.ListMoPassenger.get(i).IDNO, moRequest.ListMoPassenger.get(i).nationality, moRequest.ListMoPassenger.get(i).docHolderInd, moRequest.ListMoPassenger.get(i).docIssueCountry,
                                dateProcessing(moRequest.ListMoPassenger.get(i).Birthday), moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", moRequest.ListMoPassenger.get(i).IDValidDate, (i + 1),
                                moRequest.ListMoPassenger.get(i).englishSurname, moRequest.ListMoPassenger.get(i).englishName, (i + 1), (adt_chd.size() + i + 1));
                        for (int j = 0; j < moRequest.ListGoSegment.size(); j++) {
                            str += String.format("<FlightSegmentRPH>%s</FlightSegmentRPH>", (j + 1));
                        }
                        if (moRequest.ListBackSegment != null && moRequest.ListBackSegment.size() > 0) {
                            for (MoSegment moSegment : moRequest.ListBackSegment) {
                                str += String.format("<FlightSegmentRPH>%s</FlightSegmentRPH>", (moRequest.ListGoSegment.size() + 1));
                            }
                        }
                        str += String.format("</FlightSegmentRPHs>\n" +
                                "        </AirTraveler>\n");
                        inf.remove(0);
                    } else {
                        str += String.format("<AirTraveler PassengerTypeCode=\"%s\" Gender=\"%s\">\n" +
                                        "    <PersonName LanguageType=\"EN\">\n" +
                                        "        <Surname>%s</Surname>\n" +
                                        "    </PersonName>\n" +
                                        "    <Document DocType=\"PP\" DocTypeDetail=\"P\" DocID=\"%s\" DocHolderNationality=\"%s\"\n" +
                                        "DocHolderInd=\"%s\" DocIssueCountry=\"%s\" BirthDate=\"%s\" Gender=\"%s\" ExpireDate=\"%s\" RPH=\"%s\">\n" +
                                        "        <DocHolderFormattedName>\n" +
                                        "            <GivenName>%s</GivenName>\n" +
                                        "            <Surname>%s</Surname>\n" +
                                        "        </DocHolderFormattedName>\n" +
                                        "    </Document>\n" +
                                        "    <TravelerRefNumber RPH=\"%s\"/>\n" +
                                        "</AirTraveler>", PassengerType, moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", moRequest.ListMoPassenger.get(i).englishSurname + "/" + moRequest.ListMoPassenger.get(i).englishName,
                                moRequest.ListMoPassenger.get(i).IDNO, moRequest.ListMoPassenger.get(i).nationality, moRequest.ListMoPassenger.get(i).docHolderInd, moRequest.ListMoPassenger.get(i).docIssueCountry,
                                dateProcessing(moRequest.ListMoPassenger.get(i).Birthday), moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", moRequest.ListMoPassenger.get(i).IDValidDate, (i + 1),
                                moRequest.ListMoPassenger.get(i).englishSurname, moRequest.ListMoPassenger.get(i).englishName, (i + 1));
                    }
                } else if (PassengerType.equals("CHD")) {
                    str += String.format("<AirTraveler PassengerTypeCode=\"%s\" Gender=\"%s\">\n" +
                                    "    <PersonName LanguageType=\"EN\">\n" +
                                    "        <Surname>%s</Surname>\n" +
                                    "    </PersonName>\n" +
                                    "    <Document DocType=\"PP\" DocTypeDetail=\"P\" DocID=\"%s\" DocHolderNationality=\"%s\"\n" +
                                    "DocHolderInd=\"%s\" DocIssueCountry=\"%s\" BirthDate=\"%s\" Gender=\"%s\" ExpireDate=\"%s\" RPH=\"%s\">\n" +
                                    "        <DocHolderFormattedName>\n" +
                                    "            <GivenName>%s</GivenName>\n" +
                                    "            <Surname>%s</Surname>\n" +
                                    "        </DocHolderFormattedName>\n" +
                                    "    </Document>\n" +
                                    "    <TravelerRefNumber RPH=\"%s\"/>\n" +
                                    "</AirTraveler>", PassengerType, moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", moRequest.ListMoPassenger.get(i).englishSurname + "/" + moRequest.ListMoPassenger.get(i).englishName,
                            moRequest.ListMoPassenger.get(i).IDNO, moRequest.ListMoPassenger.get(i).nationality, moRequest.ListMoPassenger.get(i).docHolderInd, moRequest.ListMoPassenger.get(i).docIssueCountry,
                            dateProcessing(moRequest.ListMoPassenger.get(i).Birthday), moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", moRequest.ListMoPassenger.get(i).IDValidDate, (i + 1),
                            moRequest.ListMoPassenger.get(i).englishSurname, moRequest.ListMoPassenger.get(i).englishName, (i + 1));
                }
            } else {
                if (PassengerType.equals("ADT")) {
                    if (inf.size() > 0) {
                        str += String.format("<AirTraveler BirthDate=\"%s\" PassengerTypeCode=\"INF\">\n" +
                                        "            <PersonName LanguageType=\"ZH\">\n" +
                                        "                <Surname>%s</Surname>\n" +
                                        "            </PersonName>\n" +
                                        "            <PersonName LanguageType=\"EN\">\n" +
                                        "                <Surname>%s</Surname>\n" +
                                        "            </PersonName>\n" +
                                        "            <PassengerTypeQuantity Age=\"%s\" />\n" +
                                        "            <TravelerRefNumber RPH=\"%s\" />\n" +
                                        "        <FlightSegmentRPHs>\n", dateProcessing(inf.get(0).Birthday), inf.get(0).PassengerName, inf.get(0).englishSurname + "/" + inf.get(0).englishName,
                                inf.get(0).age, (adt_chd.size() + i + 1), (i + 1));
                        for (int j = 0; j < moRequest.ListGoSegment.size(); j++) {
                            str += String.format("<FlightSegmentRPH>%s</FlightSegmentRPH>", (j + 1));
                        }
                        if (moRequest.ListBackSegment != null && moRequest.ListBackSegment.size() > 0) {
                            for (MoSegment moSegment : moRequest.ListBackSegment) {
                                str += String.format("<FlightSegmentRPH>%s</FlightSegmentRPH>", (moRequest.ListGoSegment.size() + 1));
                            }
                        }
                        str += String.format("</FlightSegmentRPHs>\n" +
                                "        </AirTraveler>\n");
                        str = str + String.format(
                                "<AirTraveler Gender=\"%s\" PassengerTypeCode=\"%s\" AccompaniedByInfant=\"true\" >\n" +
                                        "       <PersonName LanguageType=\"ZH\">\n" +
                                        "           <Surname>%s</Surname>\n" +
                                        "       </PersonName>\n" +
                                        "       <Document DocType=\"%s\" DocID=\"%s\"/>\n" +
                                        "       <TravelerRefNumber RPH=\"%s\" InfantTravelerRPH=\"%s\"/>\n" +
                                        "    <FlightSegmentRPHs>\n", moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", PassengerType,
                                moRequest.ListMoPassenger.get(i).PassengerName, cardType, moRequest.ListMoPassenger.get(i).IDNO, (i + 1), (adt_chd.size() + i + 1));
                        for (int j = 0; j < moRequest.ListGoSegment.size(); j++) {
                            str += String.format("<FlightSegmentRPH>%s</FlightSegmentRPH>", (j + 1));
                        }
                        if (moRequest.ListBackSegment != null && moRequest.ListBackSegment.size() > 0) {
                            for (MoSegment moSegment : moRequest.ListBackSegment) {
                                str += String.format("<FlightSegmentRPH>%s</FlightSegmentRPH>", (moRequest.ListGoSegment.size() + 1));
                            }
                        }
                        str += String.format("</FlightSegmentRPHs>\n" +
                                "        </AirTraveler>\n");
                        inf.remove(0);
                    } else {
                        str = str + String.format(
                                "<AirTraveler Gender=\"%s\" PassengerTypeCode=\"%s\" AccompaniedByInfant=\"true\" >\n" +
                                        "       <PersonName LanguageType=\"ZH\">\n" +
                                        "           <Surname>%s</Surname>\n" +
                                        "       </PersonName>\n" +
                                        "       <Document DocType=\"%s\" DocID=\"%s\"/>\n" +
                                        "       <TravelerRefNumber RPH=\"%s\" />\n" +
                                        "    </AirTraveler>\n", moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", PassengerType,
                                moRequest.ListMoPassenger.get(i).PassengerName, cardType, moRequest.ListMoPassenger.get(i).IDNO, (i + 1));
                    }
                } else if (PassengerType.equals("CHD")) {
                    str = str + String.format(
                            "<AirTraveler Gender=\"%s\" PassengerTypeCode=\"%s\" AccompaniedByInfant=\"true\" >\n" +
                                    "       <PersonName LanguageType=\"ZH\">\n" +
                                    "           <Surname>%s</Surname>\n" +
                                    "       </PersonName>\n" +
                                    "       <Document DocType=\"%s\" DocID=\"%s\"/>\n" +
                                    "       <TravelerRefNumber RPH=\"%s\" />\n" +
                                    "    </AirTraveler>\n", moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", PassengerType,
                            moRequest.ListMoPassenger.get(i).PassengerName, cardType, moRequest.ListMoPassenger.get(i).IDNO, (i + 1));
                }
            }
            /*if (count > 0) {

                count = 0;
            } else {
                if (PassengerType.equals("ADT") || PassengerType.equals("CHD")) {
                    str = str + String.format(
                            "<AirTraveler Gender=\"%s\" PassengerTypeCode=\"%s\">\n" +
                                    "       <PersonName LanguageType=\"ZH\">\n" +
                                    "           <Surname>%s</Surname>\n" +
                                    "       </PersonName>\n" +
                                    "       <Document DocType=\"%s\" DocID=\"%s\"/>\n" +
                                    "       <TravelerRefNumber RPH=\"%s\" />\n" +
                                    "    </AirTraveler>\n", moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", PassengerType,
                            moRequest.ListMoPassenger.get(i).PassengerName, cardType, moRequest.ListMoPassenger.get(i).IDNO, (i + 1));
                } else if (PassengerType.equals("INF")) {
                    str = str + String.format(
                            "<AirTraveler Gender=\"%s\" PassengerTypeCode=\"%s\">\n" +
                                    "       <PersonName LanguageType=\"ZH\">\n" +
                                    "           <Surname>%s</Surname>\n" +
                                    "       </PersonName>\n" +
                                    "       <Document DocType=\"%s\" DocID=\"%s\"/>\n" +
                                    "       <TravelerRefNumber RPH=\"%s\" />\n" +
                                    "    </AirTraveler>\n", moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", PassengerType,
                            moRequest.ListMoPassenger.get(i).PassengerName + "INF", cardType, moRequest.ListMoPassenger.get(i).IDNO, (i + 1));
                }
            }*/
        }

        /*for (int i = 0; i < moRequest.ListMoPassenger.size(); i++) {
            String PassengerType = "ADT";
            String cardType = "NI";
            if (moRequest.ListMoPassenger.get(i).PassengerType == EnumHelper.PassengerType.成人.getValue()) {
                PassengerType = "ADT";
            }
            if (moRequest.ListMoPassenger.get(i).PassengerType == EnumHelper.PassengerType.儿童.getValue()) {
                PassengerType = "CHD";
            }
            if (moRequest.ListMoPassenger.get(i).PassengerType == EnumHelper.PassengerType.婴儿.getValue()) {
                PassengerType = "INF";
            }

            if (moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.居民身份证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.港澳台居民居住证.getValue()) {
                cardType = "NI";
            } else if (moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.护照.getValue()) {
                cardType = "PP";
            } else if (moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.港澳通行证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.大陆居民来往台湾通行证.getValue() ||
                       moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.军官证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.文职干部证.getValue() ||
                       moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.义务兵证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.士官证.getValue() ||
                       moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.文职人员证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.职工证.getValue() ||
                       moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.武警警官证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.武警士兵证.getValue() ||
                       moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.海员证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.港澳居民来往内地通行证.getValue() ||
                       moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.台湾居民来往大陆通行证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.外交部签发的驻华外交人员证.getValue() ||
                       moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.外国人永久居留证.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.出生医学证明.getValue() ||
                       moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.户口簿.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.学生证.getValue() ||
                       moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.户口所在地公安机关出具的身份证明.getValue() || moRequest.ListMoPassenger.get(i).IDType == EnumHelper.PsgerIDType.民航局规定的其他有效乘机身份证件.getValue()){
                cardType = "ID";
            } else {
                cardType = "UU";
            }
            if (count > 0) {
                if (cardType.equals("PP")) {
                    if (PassengerType.equals("ADT") || PassengerType.equals("CHD")) {
                        str += String.format("<AirTraveler PassengerTypeCode=\"%s\" Gender=\"%s\">\n" +
                                "    <PersonName LanguageType=\"EN\">\n" +
                                "        <Surname>%s</Surname>\n" +
                                "    </PersonName>\n" +
                                "    <Document DocType=\"PP\" DocTypeDetail=\"P\" DocID=\"%s\" DocHolderNationality=\"%s\"\n" +
                                "DocHolderInd=\"%s\" DocIssueCountry=\"%s\" BirthDate=\"%s\" Gender=\"%s\" ExpireDate=\"%s\" RPH=\"%s\">\n" +
                                "        <DocHolderFormattedName>\n" +
                                "            <GivenName>%s</GivenName>\n" +
                                "            <Surname>%s</Surname>\n" +
                                "        </DocHolderFormattedName>\n" +
                                "    </Document>\n" +
                                "    <TravelerRefNumber RPH=\"%s\"/>\n" +
                                "</AirTraveler>", PassengerType, moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", moRequest.ListMoPassenger.get(i).englishSurname + "/" + moRequest.ListMoPassenger.get(i).englishName,
                                moRequest.ListMoPassenger.get(i).IDNO, moRequest.ListMoPassenger.get(i).nationality, moRequest.ListMoPassenger.get(i).docHolderInd, moRequest.ListMoPassenger.get(i).docIssueCountry,
                                moRequest.ListMoPassenger.get(i).Birthday, moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", moRequest.ListMoPassenger.get(i).IDValidDate, (i + 1),
                                moRequest.ListMoPassenger.get(i).englishSurname, moRequest.ListMoPassenger.get(i).englishName, (i + 1));
                    } else if (PassengerType.equals("INF")) {
                        str += String.format("<AirTraveler PassengerTypeCode=\"%s\" Gender=\"%s\">\n" +
                                        "    <PersonName LanguageType=\"EN\">\n" +
                                        "        <Surname>%s</Surname>\n" +
                                        "    </PersonName>\n" +
                                        "    <Document DocType=\"PP\" DocTypeDetail=\"P\" DocID=\"%s\" DocHolderNationality=\"%s\"\n" +
                                        "DocHolderInd=\"%s\" DocIssueCountry=\"%s\" BirthDate=\"%s\" Gender=\"%s\" ExpireDate=\"%s\" RPH=\"%s\">\n" +
                                        "        <DocHolderFormattedName>\n" +
                                        "            <GivenName>%s</GivenName>\n" +
                                        "            <Surname>%s</Surname>\n" +
                                        "        </DocHolderFormattedName>\n" +
                                        "    </Document>\n" +
                                        "    <TravelerRefNumber RPH=\"%s\"/>\n" +
                                        "</AirTraveler>", PassengerType, moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", moRequest.ListMoPassenger.get(i).englishSurname + "/" + moRequest.ListMoPassenger.get(i).englishName + "INF",
                                moRequest.ListMoPassenger.get(i).IDNO, moRequest.ListMoPassenger.get(i).nationality, moRequest.ListMoPassenger.get(i).docHolderInd, moRequest.ListMoPassenger.get(i).docIssueCountry,
                                moRequest.ListMoPassenger.get(i).Birthday, moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", moRequest.ListMoPassenger.get(i).IDValidDate, (i + 1),
                                moRequest.ListMoPassenger.get(i).englishSurname, moRequest.ListMoPassenger.get(i).englishName, (i + 1));
                    }
                } else {
                    if (PassengerType.equals("ADT") || PassengerType.equals("CHD")) {
                        str = str + String.format(
                                "<AirTraveler Gender=\"%s\" PassengerTypeCode=\"%s\" AccompaniedByInfant=\"true\" >\n" +
                                        "       <PersonName LanguageType=\"ZH\">\n" +
                                        "           <Surname>%s</Surname>\n" +
                                        "       </PersonName>\n" +
                                        "       <Document DocType=\"%s\" DocID=\"%s\"/>\n" +
                                        "       <TravelerRefNumber RPH=\"%s\" />\n" +
                                        "    </AirTraveler>\n", moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", PassengerType,
                                moRequest.ListMoPassenger.get(i).PassengerName, cardType, moRequest.ListMoPassenger.get(i).IDNO, (i + 1));
                    } else if (PassengerType.equals("INF")) {
                        str = str + String.format(
                                "<AirTraveler Gender=\"%s\" PassengerTypeCode=\"%s\" AccompaniedByInfant=\"true\" >\n" +
                                        "       <PersonName LanguageType=\"ZH\">\n" +
                                        "           <Surname>%s</Surname>\n" +
                                        "       </PersonName>\n" +
                                        "       <Document DocType=\"%s\" DocID=\"%s\"/>\n" +
                                        "       <TravelerRefNumber RPH=\"%s\" />\n" +
                                        "    </AirTraveler>\n", moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", PassengerType,
                                moRequest.ListMoPassenger.get(i).PassengerName + "INF", cardType, moRequest.ListMoPassenger.get(i).IDNO, (i + 1));
                    }
                }
                count = 0;
            } else {
                if (PassengerType.equals("ADT") || PassengerType.equals("CHD")) {
                    str = str + String.format(
                            "<AirTraveler Gender=\"%s\" PassengerTypeCode=\"%s\">\n" +
                                    "       <PersonName LanguageType=\"ZH\">\n" +
                                    "           <Surname>%s</Surname>\n" +
                                    "       </PersonName>\n" +
                                    "       <Document DocType=\"%s\" DocID=\"%s\"/>\n" +
                                    "       <TravelerRefNumber RPH=\"%s\" />\n" +
                                    "    </AirTraveler>\n", moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", PassengerType,
                            moRequest.ListMoPassenger.get(i).PassengerName, cardType, moRequest.ListMoPassenger.get(i).IDNO, (i + 1));
                } else if (PassengerType.equals("INF")) {
                    str = str + String.format(
                            "<AirTraveler Gender=\"%s\" PassengerTypeCode=\"%s\">\n" +
                                    "       <PersonName LanguageType=\"ZH\">\n" +
                                    "           <Surname>%s</Surname>\n" +
                                    "       </PersonName>\n" +
                                    "       <Document DocType=\"%s\" DocID=\"%s\"/>\n" +
                                    "       <TravelerRefNumber RPH=\"%s\" />\n" +
                                    "    </AirTraveler>\n", moRequest.ListMoPassenger.get(i).Sex ? "MALE" : "FEMALE", PassengerType,
                            moRequest.ListMoPassenger.get(i).PassengerName + "INF", cardType, moRequest.ListMoPassenger.get(i).IDNO, (i + 1));
                }
            }
        }*/

        str += String.format("<SpecialReqDetails>\n" +
                "    <OtherServiceInformations>\n" +
                "        <OtherServiceInformation Code=\"OTHS\">\n" +
                "            <Airline Code=\"%s\"/>\n" +
                "            <Text>CTCT%s</Text>\n" +
                "        </OtherServiceInformation>\n", moRequest.ListGoSegment.get(0).Airline, moRequest.Contacts.ContactMobile);

        for (int i = 0; i < moRequest.ListMoPassenger.size(); i++) {
            str += String.format("<OtherServiceInformation Code=\"OTHS\">\n" +
                    "    <Airline Code=\"%s\"/>\n" +
                    "    <Text>CTCM%s</Text>\n" +
                    "    <TravelerRefNumber RPH=\"%s\"/>\n" +
                    "</OtherServiceInformation>\n", moRequest.ListGoSegment.get(0).Airline, moRequest.ListMoPassenger.get(i).PassengerMobile, (i + 1));
        }

        str += String.format("</OtherServiceInformations>\n" +
                        "        </SpecialReqDetails>\n" +
                        "    </TravelerInfo>\n" +
                        "    <Ticketing TicketTimeLimit=\"%s\" />\n" +
                        "    <TPA_Extensions>\n" +
                        "        <ContactInfo>023-57651234</ContactInfo>\n" +
                        "        <EnvelopType>KI</EnvelopType>\n" +
                        "        <EnvelopDelay>false</EnvelopDelay>\n" +
                        "    </TPA_Extensions>\n" +
                        "</OTA_AirBookRQ>", date(moRequest.ListGoSegment.get(0).DepDate, "yyyy-MM-dd HH:mm:ss"));

        return str;
    }


    private String date(Date date, String str) {
        SimpleDateFormat format = new SimpleDateFormat(str);
        return format.format(date);
    }

    private Date convertToDate(String str, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Date date = null;
        if (str != null) {
            try {
                date = sdf.parse(str);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return date;
    }


    /**
     * PNR结构化信息提取
     *
     * @param pnrId
     * @return
     */
    public XElement getOTAAirResRetByPnrId(String pnrId) {
        String strResponseData = "";
        String strRequestData = "";

        strRequestData = String.format("<OTA_AirResRetRQ RetCreateTimeInd=\"true\">\n" +
                "    <POS>\n" +
                "        <Source PseudoCityCode=\"%s\" />\n" +
                "    </POS>\n" +
                "    <BookingReferenceID ID=\"%s\" />\n" +
                "</OTA_AirResRetRQ>", OFFICE, pnrId);

        //请求
        strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirResRet", strRequestData);

        XElement root = XElement.loadXml(strResponseData);

        return root;
    }


    /**
     * 出票
     *
     * @param prnId        pnr
     * @param cpMark        大客户出票指令
     * @param passNameList 乘客姓名
     * @param cabin        仓位
     * @param price        价格
     * @param FuelTax      燃油
     * @param AirportTax   基建
     * @return
     */
    private XElement outTicket(String prnId, String cpMark, List<String> passNameList, String cabin, String totalPrice, String price, String FuelTax, String AirportTax) {
        String strResponseData = "";
        String strRequestData = "";
        String companyName = "";
        if (cpMark != null && !cpMark.equals("")) {
            companyName = String.format("<CompanyName Code=\"%s\" />", cpMark);
        }

        if (companyName != null && !companyName.equals("")) {
            strRequestData = String.format(
                    "<OTA_AirDemandTicketRQ>\n" +
                            "    <POS> \n" +
                            "        <Source PseudoCityCode=\"%s\" OtherID=\"1\">\n" +
                            "        </Source>\n" +
                            "    </POS>\n" +
                            "    <DemandTicketDetail ReconfirmSegmentInd=\"true\" ReturnTicketInfoInd=\"true\" LimitSegmentStatusInd=\"true\">\n" +
                            "        <BookingReferenceID ID=\"%s\" ID_Context=\"PNR\">%s</BookingReferenceID>\n" +
                            "        <PaymentInfo PaymentType=\"CASH\" CurrencyCode=\"CNY\"></PaymentInfo>\n", OFFICE, prnId, companyName);
        } else {
            strRequestData = String.format(
                    "<OTA_AirDemandTicketRQ>\n" +
                            "    <POS> \n" +
                            "        <Source PseudoCityCode=\"%s\" OtherID=\"1\">\n" +
                            "        </Source>\n" +
                            "    </POS>\n" +
                            "    <DemandTicketDetail ReconfirmSegmentInd=\"true\" ReturnTicketInfoInd=\"true\" LimitSegmentStatusInd=\"true\">\n" +
                            "        <BookingReferenceID ID=\"%s\" ID_Context=\"PNR\"></BookingReferenceID>\n" +
                            "        <PaymentInfo PaymentType=\"CASH\" CurrencyCode=\"CNY\"></PaymentInfo>\n", OFFICE, prnId);
        }

        for (int i = 0; i < passNameList.size(); i++) {
            strRequestData += String.format(
                    "       <PassengerName PassengerRefNumber=\"%s\" PassengerTypeCode=\"ADT\">\n" +
                            "           <Surname>%s</Surname>\n" +
                            "       </PassengerName>\n", (i + 1), passNameList.get(i));
        }

        strRequestData += String.format(
                "        <PTC_FareBreakdowns>\n" +
                        "            <PTC_FareBreakdown>\n" +
                        "                <PassengerTypeQuantity Code=\"ADT\" />\n" +
                        "                <FareBasisCodes>\n" +
                        "                    <FareBasisCode>%s</FareBasisCode>\n" +
                        "                </FareBasisCodes>\n" +
                        "                <PassengerFare>\n" +
                        "                    <TotalFare Amount=\"%s\" CurrencyCode=\"CNY\" />\n" +
                        "                    <BaseFare Amount=\"%s\" CurrencyCode=\"CNY\" />\n" +
                        "                    <Taxes>\n" +
                        "                        <Tax TaxCode=\"CN\" Amount=\"%s\" CurrencyCode=\"CNY\" />\n" +
                        "                        <Tax TaxCode=\"YQ\" Amount=\"%s\" CurrencyCode=\"CNY\" />\n" +
                        "                    </Taxes>\n" +
                        "                </PassengerFare>\n" +
                        "            </PTC_FareBreakdown>\n" +
                        "        </PTC_FareBreakdowns>\n" +
                        "    </DemandTicketDetail>\n" +
                        "</OTA_AirDemandTicketRQ>", cabin, totalPrice, price, AirportTax, FuelTax);

        //请求
        strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirDemandTicket", strRequestData);

        XElement root = XElement.loadXml(strResponseData);

        return root;

    }


    /**
     * 计算运价
     *
     * @param pnrId pnr
     * @param
     * @return
     */
    public CalculationResponse calculationFreight(String pnrId) {
        CalculationResponse response = new CalculationResponse();

        String strResponseData = "";
        String strRequestData = "";
        strRequestData = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<OTA_AirPriceRQ TransactionIdentifier=\"PAT\">\n" +
                "    <POS>\n" +
                "        <Source PseudoCityCode=\"%s\" />\n" +
                "    </POS>\n" +
                "    <TravelerInfoSummary>\n" +
                "        <AirTravelerAvail>\n" +
                "            <PassengerTypeQuantity Code=\"ADT\" />\n" +
                "        </AirTravelerAvail>\n" +
                "        <PaymentDetail PaymentType=\"CASH\" />\n" +
                "    </TravelerInfoSummary>\n" +
                "    <BookingReferenceID ID=\"%s\" />\n" +
                "</OTA_AirPriceRQ>", OFFICE, pnrId);


        try {
            //请求
            strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirPrice/D", strRequestData);

            XElement root = XElement.loadXml(strResponseData);
            if (root.toString().contains("Errors")) {
                String code = root.element("Errors").element("Error").getAttributeValue("Code");
                String msg = root.element("Errors").element("Error").getAttributeValue("ShortTextZH");
                response.setCode(code);
                response.setMsg(msg);
                response.setSuccess(false);
                return response;
            }

            XmlMapper xmlMapper = new XmlMapper();

            XElement itInTotalFare = root.element("PricedItineraries").element("PricedItinerary").element("AirItineraryPricingInfo").element("ItinTotalFare");
            //支付金额
            String amount = itInTotalFare.element("BaseFare").getAttributeValue("Amount");
            List<XElement> taxList = itInTotalFare.element("Taxes").elements("Tax");
            //基建
            String airPortTax = taxList.get(0).getAttributeValue("Amount");
            //燃油
            String fuelTax = taxList.get(1).getAttributeValue("Amount");
            //仓位
            String fareBasisCode = xmlMapper.readValue(itInTotalFare.element("FareBasisCodes").element("FareBasisCode").toString(), String.class);

            response.setSuccess(true);
            response.setAirportTax(airPortTax);
            response.setFareBasisCode(fareBasisCode);
            response.setFuelTax(fuelTax);
            response.setAmount(amount);


        } catch (JsonProcessingException e) {
            response.setCode(EnumHelper.ReturnCode.系统异常代码.toString());
            response.setMsg(e.getMessage());
            return response;
        }

        return response;

    }


    /**
     * 根据机场三字码获取机场名称
     *
     * @return
     */
    private String getAirPortNameByRirPortCode(String airPortCode) {
        if (airportService == null) {
            return airPortCode;
        }
        Airport airport = airportService.getAirPortNameByRirPortCode(airPortCode);
        return airport.getAirnamesort();
    }


    /**
     * 分离PNR
     *
     * @return
     */
    public XElement separatePNR(List<MoPassenger> ps, String pnrId) {
        String strResponseData = "";
        String strRequestData = "";

        strRequestData = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<OTA_AirBookModifyRQ>\n" +
                "    <POS>\n" +
                "        <Source PseudoCityCode=\"%s\" />\n" +
                "    </POS>\n" +
                "    <AirBookModifyRQ ModificationType=\"PNR_SPLIT\">\n" +
                "        <AirReservation>\n" +
                "            <TravelerInfo>", OFFICE);

        if (ps != null && ps.size() > 0) {
            for (int i = 0; i < ps.size(); i++) {
                String PassengerType = "ADT";
                String cardType = "NI";
                if (ps.get(i).PassengerType == EnumHelper.PassengerType.成人.getValue()) {
                    PassengerType = "ADT";
                }
                if (ps.get(i).PassengerType == EnumHelper.PassengerType.儿童.getValue()) {
                    PassengerType = "CHD";
                }
                if (ps.get(i).PassengerType == EnumHelper.PassengerType.婴儿.getValue()) {
                    PassengerType = "INF";
                }
                if (ps.get(i).IDType == EnumHelper.PsgerIDType.居民身份证.getValue() || ps.get(i).IDType == EnumHelper.PsgerIDType.港澳台居民居住证.getValue()) {
                    cardType = "NI";
                } else if (ps.get(i).IDType == EnumHelper.PsgerIDType.护照.getValue()) {
                    cardType = "PP";
                } else if (ps.get(i).IDType == EnumHelper.PsgerIDType.港澳通行证.getValue() || ps.get(i).IDType == EnumHelper.PsgerIDType.大陆居民来往台湾通行证.getValue() ||
                        ps.get(i).IDType == EnumHelper.PsgerIDType.军官证.getValue() || ps.get(i).IDType == EnumHelper.PsgerIDType.文职干部证.getValue() ||
                        ps.get(i).IDType == EnumHelper.PsgerIDType.义务兵证.getValue() || ps.get(i).IDType == EnumHelper.PsgerIDType.士官证.getValue() ||
                        ps.get(i).IDType == EnumHelper.PsgerIDType.文职人员证.getValue() || ps.get(i).IDType == EnumHelper.PsgerIDType.职工证.getValue() ||
                        ps.get(i).IDType == EnumHelper.PsgerIDType.武警警官证.getValue() || ps.get(i).IDType == EnumHelper.PsgerIDType.武警士兵证.getValue() ||
                        ps.get(i).IDType == EnumHelper.PsgerIDType.海员证.getValue() || ps.get(i).IDType == EnumHelper.PsgerIDType.港澳居民来往内地通行证.getValue() ||
                        ps.get(i).IDType == EnumHelper.PsgerIDType.台湾居民来往大陆通行证.getValue() || ps.get(i).IDType == EnumHelper.PsgerIDType.外交部签发的驻华外交人员证.getValue() ||
                        ps.get(i).IDType == EnumHelper.PsgerIDType.外国人永久居留证.getValue() || ps.get(i).IDType == EnumHelper.PsgerIDType.出生医学证明.getValue() ||
                        ps.get(i).IDType == EnumHelper.PsgerIDType.户口簿.getValue() || ps.get(i).IDType == EnumHelper.PsgerIDType.学生证.getValue() ||
                        ps.get(i).IDType == EnumHelper.PsgerIDType.户口所在地公安机关出具的身份证明.getValue() || ps.get(i).IDType == EnumHelper.PsgerIDType.民航局规定的其他有效乘机身份证件.getValue()){
                    cardType = "ID";
                } else {
                    cardType = "UU";
                }

                strRequestData += String.format("" +
                        "<AirTraveler PassengerTypeCode=\"%s\" AccompaniedByInfant=\"false\">\n" +
                        "           <PersonName LanguageType=\"ZH\">\n" +
                        "              <Surname>%s</Surname>\n" +
                        "           </PersonName>\n" +
                        "           <Document DocType=\"%s\" DocID=\"%s\" />\n" +
                        "           <TravelerRefNumber RPH=\"%s\" />\n" +
                        "       </AirTraveler>", PassengerType, ps.get(i).PassengerName, cardType, ps.get(i).IDNO, (i + 1));
            }
        }

        strRequestData += String.format("</TravelerInfo>\n" +
                "        </AirReservation>\n" +
                "    </AirBookModifyRQ>\n" +
                "    <AirReservation>\n" +
                "        <BookingReferenceID ID=\"%s\" />\n" +
                "    </AirReservation>\n" +
                "</OTA_AirBookModifyRQ>", pnrId);


        //请求
        strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirBookModify", strRequestData);
        XElement root = XElement.loadXml(strResponseData);
        return root;
    }

    /**
     * prn原文信息提取
     * @param pnr
     * @return
     */
    public XElement airResRetCompleteRQ(String pnr) {
        String strRequestData = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<TES_AirResRetCompleteRQ>\n" +
                "    <POS>\n" +
                "        <Source PseudoCityCode=\"%S\">\n" +
                "        </Source>\n" +
                "    </POS>\n" +
                "    <BookingReferenceID ID=\"%s\">\n" +
                "    </BookingReferenceID>\n" +
                "    <RetrieveType Type=\"ActiveRaw\" />\n" +
                "</TES_AirResRetCompleteRQ>", OFFICE, pnr);

        //请求
        String strResponse = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirResRetComplete", strRequestData);
        XElement root = XElement.loadXml(strResponse);
        return root;
    }


    /**
     * No位补位
     */
    private XElement noComplement(String pnrId, List<FlightOrderInfoTickets> ticketList) {
        //去程
        List<FlightOrderInfoTickets> goCollect = ticketList.stream().filter(item -> {
            return item.getTripType().equals(FlightOrderConstants.ow.toString());
        }).collect(Collectors.toList());

        //返程
        List<FlightOrderInfoTickets> backCollect = ticketList.stream().filter(item -> {
            return item.getTripType().equals(FlightOrderConstants.rt.toString());
        }).collect(Collectors.toList());


        String strResponseData = "";
        String reqStrData = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<OTA_AirBookModifyRQ>\n" +
                "    <POS>\n" +
                "        <Source PseudoCityCode=\"%s\" />\n" +
                "    </POS>\n" +
                "    <AirBookModifyRQ ModificationType=\"SEGMENT_NO\" ModificationInfo=\"K\">\n" +
                "        <AirReservation>\n" +
                "            <AirItinerary>\n" +
                "                <OriginDestinationOptions>\n" +
                "                    <OriginDestinationOption>", OFFICE);

        //去程
        if (goCollect.size() > 0) {
            reqStrData += complementRequest(goCollect, 1);
        }

        //返程
        if (backCollect.size() > 0) {
            reqStrData += complementRequest(backCollect, 2);
        }

        reqStrData += String.format("                   </OriginDestinationOption>\n" +
                "                </OriginDestinationOptions>\n" +
                "            </AirItinerary>\n" +
                "        </AirReservation>\n" +
                "    </AirBookModifyRQ>\n" +
                "    <AirReservation>\n" +
                "        <BookingReferenceID ID=\"%s\" />\n" +
                "    </AirReservation>\n" +
                "</OTA_AirBookModifyRQ>", pnrId);


        strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirBookModify", reqStrData);
        logger.info("no位接口返回值" + strResponseData);
        XElement root = XElement.loadXml(strResponseData);

        return root;

    }

    private String complementRequest(List<FlightOrderInfoTickets> list, int RPH) {

        FlightOrderInfoTickets infoTickets = list.get(0);
        //获取机场三字码
        String dstAirport = infoTickets.getOrgAirport();
        String orgAirport = infoTickets.getDstAirport();

        //航班号
        String flightNo = infoTickets.getFlight();
        String newFlightNo = flightNo.substring(2);
        //乘机人数量
        int count = list.size();

        //日期
        String date = date(infoTickets.getDepartureTime(), "yyyy-MM-ddHH:mm:ss");
        String newDate = insertStr(date, 10, "T");


        String reqStrData = String.format("\n                         <FlightSegment RPH=\"%s\" DepartureDateTime=\"%s\" FlightNumber=\"%s\" NumberInParty=\"%s\" Status=\"NN\" SegmentType=\"NORMAL\">\n" +
                        "                           <OperatingAirline Code=\"%s\" FlightNumber=\"%s\" />\n" +
                        "                           <DepartureAirport LocationCode=\"%s\" />\n" +
                        "                           <ArrivalAirport LocationCode=\"%s\" />\n" +
                        "                           <MarketingAirline Code=\"%s\" />\n" +
                        "                           <BookingClassAvail ResBookDesigCode=\"%s\" />\n" +
                        "                         </FlightSegment>\n", RPH, newDate, newFlightNo, count,
                infoTickets.getAirliner(), newFlightNo, dstAirport, orgAirport,
                infoTickets.getAirliner(), infoTickets.getCabin());

        return reqStrData;
    }

    /**
     * 电子客票提取（查询出票后的状态，已使用 | 未使用）
     *
     * @param pnr
     * @return
     */
    public TicketInfoResponse ticketInfo(String pnr) {
        TicketInfoResponse response = new TicketInfoResponse();
        String strResponseData = "";
        String reqStrData = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<TES_AirTicketRetRQ SysType=\"C\">\n" +
                "    <POS>\n" +
                "        <Source PseudoCityCode=\"%s\">\n" +
                "            <RequestorID>\n" +
                "                <CompanyName Code=\"GS\" />\n" +
                "            </RequestorID>\n" +
                "        </Source>\n" +
                "    </POS>\n" +
                "    <BookingReferenceID ID=\"%s\" />\n" +
                "</TES_AirTicketRetRQ>", OFFICE, pnr);

        try {
            strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketRet", reqStrData);

            XElement root = XElement.loadXml(strResponseData);
            //错误处理
            if (root.toString().contains("Errors")) {
                XElement element = root.element("Errors").element("Error");
                response.setCode(element.getAttributeValue("Code"));
                response.setMsg(element.getAttributeValue("ShortTextZH"));
                response.setSuccess(false);
                return response;
            }

            XElement element = root.element("AirTicketRet").element("FlightSegments").element("FlightSegment");

            String ticketStatus = element.getAttributeValue("TicketStatus");
            if ("OPEN FOR USE".equals(ticketStatus)) {
                response.setSuccess(true);
                response.setMsg("票号未使用");
            } else {
                response.setSuccess(false);
                response.setMsg("票号已使用,不能退票!");
            }

        } catch (Exception e) {
            response.setCode(EnumHelper.ReturnCode.系统异常代码.toString());
            response.setMsg(e.getMessage());
            return response;
        }

        return response;

    }


    /**
     * 分离pnr确认退票请求
     *
     * @return
     */
    public CalculateRefundRes autoRefundTickets(Long orderId, List<String> ticketNo) {
        CalculateRefundRes response = new CalculateRefundRes();
        BigDecimal totalAmount = new BigDecimal("0.0");
        BigDecimal totalDeduction = new BigDecimal("0.0");
        BigDecimal totalNetRefund = new BigDecimal("0.0");
        String totalTicketNumber = "";
        String success = "";
        try {
            String refundNumber = "";
            for (String ticket : ticketNo) {
                String strResponseData = "";
                String reqStrData = String.format("<TES_AirTicketRefundRQ>\n" +
                        "    <POS>\n" +
                        "        <Source PseudoCityCode=\"%s\" />\n" +
                        "    </POS>\n" +
                        "    <TicketRefundInfoDetails>\n" +
                        "        <TicketRefundInfoDetail ReturnRefundFormInfoInd=\"true\" ConfirmRefundInd=\"true\">\n" +
                        "            <TicketItemInfo TicketNumber=\"%s\" />\n" +
                        "            <PrinterInfo Number=\"1\" Type=\"BSP_DOMESTIC_ETICKET\" />\n" +
                        "        </TicketRefundInfoDetail>\n" +
                        "    </TicketRefundInfoDetails>\n" +
                        "</TES_AirTicketRefundRQ>", OFFICE, ticket);

                strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketRefund", reqStrData);
                XElement root = XElement.loadXml(strResponseData);
                XmlMapper xmlMapper = new XmlMapper();
                if (root.toString().contains("Errors")) {
                    response.setSuccess(false);
                    response.setMsg(root.element("Errors").element("Error").getAttributeValue("ShortText"));
                    response.setCode(root.element("Errors").element("Error").getAttributeValue("Code"));
                    return response;
                }

                success = xmlMapper.readValue(root.element("Success").toString(), String.class);
                //净退额
                String NetRefund = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("NetRefund");
                //扣款
                String Deduction = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("Deduction");
                //手续费
                String Amount = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("CommissionInfo").element("Base").getAttributeValue("Amount");
                //票号
                String TicketNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("TicketItemInfo").getAttributeValue("TicketNumber");
                //退票单号
                refundNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").getAttributeValue("Number");
                totalAmount = totalAmount.add(new BigDecimal(Amount));
                totalDeduction = totalDeduction.add(new BigDecimal(Deduction));
                totalNetRefund = totalNetRefund.add(new BigDecimal(NetRefund));
                totalTicketNumber += TicketNumber + ",";

                //TODO 其他字段
                response.getNumber().add(totalTicketNumber.substring(0, totalTicketNumber.length() - 1));
            }
            FlightOrderInfo orderInfo = orderInfoService.selectFlightOrderInfo(String.valueOf(orderId)); //获取订单主表信息
            //退改签记录
            FlightOrderChange orderChange = new FlightOrderChange();
            SnowflakeUtils snowflakeUtils = new SnowflakeUtils();
            orderChange.setChangeOrderId(snowflakeUtils.nextId() + "-T"); //退票标识主键
            orderChange.setIsdealing("1"); //是否处理（0否，1是）
            //TODO 退款原因（1自愿，非自愿2）、核销手续费
            orderChange.setCardnumber(orderInfo.getCustomerCardId());
            orderChange.setCardholder(orderInfo.getCustomerName());
            orderChange.setOrderId(String.valueOf(orderId)); //订单基本信息id
            orderChange.setChangeStatus(FlightOrderConstants.refundTicketStatus_success.getValue()); //退票状态
            orderChange.setAddTime(DateUtils.getNowDate()); //退废申请时间
            orderChange.setChangeType(FlightOrderChangeConstants.refund.getValue());
            orderChange.setRefundNumber(refundNumber);
            orderChange.setChangeFee(new BigDecimal(20));
            flightOrderChangeService.insertFlightOrderChange(orderChange);

            orderInfo.setChangeOrderId(orderChange.getChangeOrderId());
            orderInfoService.updateFlightOrderInfo(orderInfo);
            for (String tickets : ticketNo) {
                List<FlightOrderInfoTickets> orderInfoTickets = orderInfoTicketsService.getFlightOrderInfoByTicketNoList(tickets);
                if (orderInfo.getTripType().equals(FlightOrderConstants.ow.toString())) {
                    FlightOrderChangeTickets orderChangeTickets = new FlightOrderChangeTickets();
                    orderChangeTickets.setChangeTicketId(snowflakeUtils.nextId());
                    orderChangeTickets.setOrderId(Long.valueOf(orderId));
                    orderChangeTickets.setChangeOrderId(orderChange.getChangeOrderId());
                    orderChangeTickets.setFlight(orderInfoTickets.get(0).getFlight());
                    orderChangeTickets.setAirliner(orderInfoTickets.get(0).getAirliner());
                    orderChangeTickets.setCustomerId(orderInfo.getCustomerId());
                    orderChangeTickets.setDepartureTime(orderInfoTickets.get(0).getDepartureTime());
                    orderChangeTickets.setIdTypeId(orderInfoTickets.get(0).getIdTypeId());
                    orderChangeTickets.setGuestName(orderInfoTickets.get(0).getGuestName());
                    orderChangeTickets.setTicketPrice(orderInfoTickets.get(0).getTicketPrice());
                    orderChangeTickets.setCabin(orderInfoTickets.get(0).getCabin());
                    orderChangeTickets.setArrivalTime(orderInfoTickets.get(0).getArrivalTime());
                    orderChangeTickets.setGuestType(orderInfoTickets.get(0).getGuestType());
                    orderChangeTickets.setGuestBirthday(orderInfoTickets.get(0).getGuestBirthday());
                    orderChangeTickets.setGuestIdno(orderInfoTickets.get(0).getGuestIdno());
                    orderChangeTickets.setOldTicketNo(orderInfoTickets.get(0).getTicketNo());
                    orderChangeTickets.setPlaneStyle(orderInfoTickets.get(0).getFlightType());
                    orderChangeTickets.setDepTerm(orderInfoTickets.get(0).getDepTerm());
                    orderChangeTickets.setArrTerm(orderInfoTickets.get(0).getArrTerm());
                    orderChangeTickets.setPnr(orderInfo.getPnr());
                    orderChangeTickets.setBigPnr(orderInfo.getBigpnr());
                    orderChangeTickets.setDeparture(orderInfoTickets.get(0).getDeparture());
                    orderChangeTickets.setArrival(orderInfoTickets.get(0).getArrival());
                    orderChangeTickets.setOrgAirport(orderInfoTickets.get(0).getOrgAirport());
                    orderChangeTickets.setDstAirport(orderInfoTickets.get(0).getDstAirport());
                    orderChangeTickets.setGuestMobile(orderInfoTickets.get(0).getGuestMobile());
                    orderChangeTickets.setActionCode("XX");
                    changeTicketsService.insertFlightOrderChangeTickets(orderChangeTickets);
                } else if (orderInfo.getTripType().equals(FlightOrderConstants.rt.toString())) {
                    orderInfoTickets.forEach(item -> {
                        FlightOrderChangeTickets orderChangeTickets = new FlightOrderChangeTickets();
                        orderChangeTickets.setChangeTicketId(snowflakeUtils.nextId());
                        orderChangeTickets.setOrderId(Long.valueOf(orderId));
                        orderChangeTickets.setChangeOrderId(orderChange.getChangeOrderId());
                        orderChangeTickets.setFlight(item.getFlight());
                        orderChangeTickets.setAirliner(item.getAirliner());
                        orderChangeTickets.setCustomerId(orderInfo.getCustomerId());
                        orderChangeTickets.setDepartureTime(item.getDepartureTime());
                        orderChangeTickets.setIdTypeId(item.getIdTypeId());
                        orderChangeTickets.setGuestName(item.getGuestName());
                        orderChangeTickets.setTicketPrice(item.getTicketPrice());
                        orderChangeTickets.setCabin(item.getCabin());
                        orderChangeTickets.setArrivalTime(item.getArrivalTime());
                        orderChangeTickets.setGuestType(item.getGuestType());
                        orderChangeTickets.setGuestBirthday(item.getGuestBirthday());
                        orderChangeTickets.setGuestIdno(item.getGuestIdno());
                        orderChangeTickets.setOldTicketNo(item.getTicketNo());
                        orderChangeTickets.setPlaneStyle(item.getFlightType());
                        orderChangeTickets.setDepTerm(item.getDepTerm());
                        orderChangeTickets.setArrTerm(item.getArrTerm());
                        orderChangeTickets.setPnr(orderInfo.getPnr());
                        orderChangeTickets.setBigPnr(orderInfo.getBigpnr());
                        orderChangeTickets.setDeparture(item.getDeparture());
                        orderChangeTickets.setArrival(item.getArrival());
                        orderChangeTickets.setOrgAirport(item.getOrgAirport());
                        orderChangeTickets.setDstAirport(item.getDstAirport());
                        orderChangeTickets.setGuestMobile(item.getGuestMobile());
                        orderChangeTickets.setActionCode("XX");
                        changeTicketsService.insertFlightOrderChangeTickets(orderChangeTickets);
                    });
                }
            }
            response.setAmount(totalAmount.toString());
            response.setDeduction(totalDeduction.toString());
            response.setNetRefund(totalNetRefund.toString());
            response.setSuccess(true);
            response.setMsg(success);

        } catch (Exception e) {
            response.setSuccess(false);
            response.setCode(EnumHelper.ReturnCode.系统异常代码.toString());
            response.setMsg(e.getMessage());
            return response;
        }

        return response;

    }

    /**
     * 分离pnr确认退票请求(CRM)
     *
     * @return
     */
    public CalculateRefundRes autoRefundTicketsCRM(List<String> ticketNo) {
        CalculateRefundRes response = new CalculateRefundRes();
        BigDecimal totalAmount = new BigDecimal("0.0");
        BigDecimal totalDeduction = new BigDecimal("0.0");
        BigDecimal totalNetRefund = new BigDecimal("0.0");
        String totalTicketNumber = "";
        String success = "";
        try {
            String refundNumber = "";
            for (String ticket : ticketNo) {
                String strResponseData = "";
                String reqStrData = String.format("<TES_AirTicketRefundRQ>\n" +
                        "    <POS>\n" +
                        "        <Source PseudoCityCode=\"%s\" />\n" +
                        "    </POS>\n" +
                        "    <TicketRefundInfoDetails>\n" +
                        "        <TicketRefundInfoDetail ReturnRefundFormInfoInd=\"true\" ConfirmRefundInd=\"true\">\n" +
                        "            <TicketItemInfo TicketNumber=\"%s\" />\n" +
                        "            <PrinterInfo Number=\"1\" Type=\"BSP_DOMESTIC_ETICKET\" />\n" +
                        "        </TicketRefundInfoDetail>\n" +
                        "    </TicketRefundInfoDetails>\n" +
                        "</TES_AirTicketRefundRQ>", OFFICE, ticket);

                strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketRefund", reqStrData);
                XElement root = XElement.loadXml(strResponseData);
                XmlMapper xmlMapper = new XmlMapper();
                if (root.toString().contains("Errors")) {
                    response.setSuccess(false);
                    response.setMsg(root.element("Errors").element("Error").getAttributeValue("ShortText"));
                    response.setCode(root.element("Errors").element("Error").getAttributeValue("Code"));
                    return response;
                }

                success = xmlMapper.readValue(root.element("Success").toString(), String.class);
                //净退额
                String NetRefund = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("NetRefund");
                //扣款
                String Deduction = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("Deduction");
                //手续费
                String Amount = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("CommissionInfo").element("Base").getAttributeValue("Amount");
                //票号
                String TicketNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("TicketItemInfo").getAttributeValue("TicketNumber");
                //退票单号
                refundNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").getAttributeValue("Number");
                totalAmount = totalAmount.add(new BigDecimal(Amount));
                totalDeduction = totalDeduction.add(new BigDecimal(Deduction));
                totalNetRefund = totalNetRefund.add(new BigDecimal(NetRefund));
                totalTicketNumber += TicketNumber + ",";

                //TODO 其他字段
                response.getNumber().add(totalTicketNumber.substring(0, totalTicketNumber.length() - 1));
            }
            response.setRefundNumber(refundNumber);
            response.setAmount(totalAmount.toString());
            response.setDeduction(totalDeduction.toString());
            response.setNetRefund(totalNetRefund.toString());
            response.setSuccess(true);
            response.setMsg(success);

        } catch (Exception e) {
            response.setSuccess(false);
            response.setCode(EnumHelper.ReturnCode.系统异常代码.toString());
            response.setMsg(e.getMessage());
            return response;
        }

        return response;

    }


    /**
     * 确认退票请求
     *
     * @return
     */
    public CalculateRefundRes autoRefundTicket(String orderId, List<MoPassenger> ticketNo) {
        CalculateRefundRes response = new CalculateRefundRes();
        BigDecimal totalAmount = new BigDecimal("0.0");
        BigDecimal totalDeduction = new BigDecimal("0.0");
        BigDecimal totalNetRefund = new BigDecimal("0.0");
        String totalTicketNumber = "";
        String success = "";
        try {
            FlightOrderInfo orderInfo = orderInfoService.selectFlightOrderInfo(orderId); //获取订单主表信息
            Long baseOrderId = orderInfo.getOrderId();//获取ID


            //获取订单详细信息
            List<FlightOrderInfoTickets> ticketList = orderInfoTicketsService.selectOrderInfoTicketByOrderId(baseOrderId);

            String refundNumber = "";
            if (orderInfo.getTripType().equals(FlightOrderConstants.ow.toString())) {
                for (FlightOrderInfoTickets flightOrderInfoTickets : ticketList) {
                    String strResponseData = "";
                    String reqStrData = String.format("<TES_AirTicketRefundRQ>\n" +
                            "    <POS>\n" +
                            "        <Source PseudoCityCode=\"%s\" />\n" +
                            "    </POS>\n" +
                            "    <TicketRefundInfoDetails>\n" +
                            "        <TicketRefundInfoDetail ReturnRefundFormInfoInd=\"true\" ConfirmRefundInd=\"true\">\n" +
                            "            <TicketItemInfo TicketNumber=\"%s\" />\n" +
                            "            <PrinterInfo Number=\"1\" Type=\"BSP_DOMESTIC_ETICKET\" />\n" +
                            "        </TicketRefundInfoDetail>\n" +
                            "    </TicketRefundInfoDetails>\n" +
                            "</TES_AirTicketRefundRQ>", OFFICE, flightOrderInfoTickets.getTicketNo());

                    strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketRefund", reqStrData);
                    XElement root = XElement.loadXml(strResponseData);
                    XmlMapper xmlMapper = new XmlMapper();
                    if (root.toString().contains("Errors")) {
                        response.setSuccess(false);
                        response.setMsg(root.element("Errors").element("Error").getAttributeValue("ShortText"));
                        response.setCode(root.element("Errors").element("Error").getAttributeValue("Code"));
                        return response;
                    }

                    success = xmlMapper.readValue(root.element("Success").toString(), String.class);
                    //净退额
                    String NetRefund = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("NetRefund");
                    //扣款
                    String Deduction = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("Deduction");
                    //手续费
                    String Amount = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("CommissionInfo").element("Base").getAttributeValue("Amount");
                    //票号
                    String TicketNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("TicketItemInfo").getAttributeValue("TicketNumber");
                    //退票单号
                    refundNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").getAttributeValue("Number");
                    totalAmount = totalAmount.add(new BigDecimal(Amount));
                    totalDeduction = totalDeduction.add(new BigDecimal(Deduction));
                    totalNetRefund = totalNetRefund.add(new BigDecimal(NetRefund));
                    totalTicketNumber += TicketNumber + ",";

                    ticketList.forEach(item -> {
                        item.setGuestStatus("2");
                        orderInfoTicketsService.updateFlightOrderInfoTickets(item);
                    });
                    //TODO 其他字段
                    response.getNumber().add(totalTicketNumber.substring(0, totalTicketNumber.length() - 1));
                }
            } else if (orderInfo.getTripType().equals(FlightOrderConstants.rt.toString())) {
                for (MoPassenger passenger : ticketNo) {
                    String strResponseData = "";
                    String reqStrData = String.format("<TES_AirTicketRefundRQ>\n" +
                            "    <POS>\n" +
                            "        <Source PseudoCityCode=\"%s\" />\n" +
                            "    </POS>\n" +
                            "    <TicketRefundInfoDetails>\n" +
                            "        <TicketRefundInfoDetail ReturnRefundFormInfoInd=\"true\" ConfirmRefundInd=\"true\">\n" +
                            "            <TicketItemInfo TicketNumber=\"%s\" />\n" +
                            "            <PrinterInfo Number=\"1\" Type=\"BSP_DOMESTIC_ETICKET\" />\n" +
                            "        </TicketRefundInfoDetail>\n" +
                            "    </TicketRefundInfoDetails>\n" +
                            "</TES_AirTicketRefundRQ>", OFFICE, passenger.TicketNo);

                    strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketRefund", reqStrData);
                    XElement root = XElement.loadXml(strResponseData);
                    XmlMapper xmlMapper = new XmlMapper();
                    if (root.toString().contains("Errors")) {
                        response.setSuccess(false);
                        response.setMsg(root.element("Errors").element("Error").getAttributeValue("ShortText"));
                        response.setCode(root.element("Errors").element("Error").getAttributeValue("Code"));
                        return response;
                    }

                    success = xmlMapper.readValue(root.element("Success").toString(), String.class);
                    //净退额
                    String NetRefund = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("NetRefund");
                    //扣款
                    String Deduction = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("Deduction");
                    //手续费
                    String Amount = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("CommissionInfo").element("Base").getAttributeValue("Amount");
                    //票号
                    String TicketNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("TicketItemInfo").getAttributeValue("TicketNumber");
                    //退票单号
                    refundNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").getAttributeValue("Number");
                    totalAmount = totalAmount.add(new BigDecimal(Amount));
                    totalDeduction = totalDeduction.add(new BigDecimal(Deduction));
                    totalNetRefund = totalNetRefund.add(new BigDecimal(NetRefund));
                    totalTicketNumber += TicketNumber + ",";

                    ticketList.forEach(item -> {
                        ticketNo.forEach(items -> {
                            if (item.getTicketNo().equals(items.TicketNo)) {
                                item.setGuestStatus("2");
                                orderInfoTicketsService.updateFlightOrderInfoTickets(item);
                            }
                        });
                    });
                    //TODO 其他字段
                    response.getNumber().add(totalTicketNumber.substring(0, totalTicketNumber.length() - 1));
                }
            }

            //退改签记录
            FlightOrderChange orderChange = new FlightOrderChange();
            SnowflakeUtils snowflakeUtils = new SnowflakeUtils();
            orderChange.setChangeOrderId(snowflakeUtils.nextId() + "-T"); //退票标识主键
            orderChange.setIsdealing("1"); //是否处理（0否，1是）
            orderChange.setCardnumber(orderInfo.getCustomerCardId());
            orderChange.setCardholder(orderInfo.getCustomerName());
            //TODO 退款原因（1自愿，非自愿2）、核销手续费
            orderChange.setOrderId(String.valueOf(baseOrderId)); //订单基本信息id
            orderChange.setChangeStatus(FlightOrderConstants.refundTicketStatus_success.getValue()); //退票状态
            orderChange.setAddTime(DateUtils.getNowDate()); //退废申请时间
            orderChange.setChangeType(FlightOrderChangeConstants.refund.getValue());
            orderChange.setRefundNumber(refundNumber);
            orderChange.setChangeFee(new BigDecimal(20));
            flightOrderChangeService.insertFlightOrderChange(orderChange);
            orderInfo.setChangeOrderId(orderChange.getChangeOrderId());
            orderInfoService.updateFlightOrderInfo(orderInfo);
            for (FlightOrderInfoTickets orderInfoTickets : ticketList) {
                FlightOrderChangeTickets orderChangeTickets = new FlightOrderChangeTickets();
                orderChangeTickets.setChangeTicketId(snowflakeUtils.nextId());
                orderChangeTickets.setOrderId(Long.valueOf(orderId));
                orderChangeTickets.setChangeOrderId(orderChange.getChangeOrderId());
                orderChangeTickets.setFlight(orderInfoTickets.getFlight());
                orderChangeTickets.setAirliner(orderInfoTickets.getAirliner());
                orderChangeTickets.setCustomerId(orderInfo.getCustomerId());
                orderChangeTickets.setDepartureTime(orderInfoTickets.getDepartureTime());
                orderChangeTickets.setIdTypeId(orderInfoTickets.getIdTypeId());
                orderChangeTickets.setGuestName(orderInfoTickets.getGuestName());
                orderChangeTickets.setTicketPrice(orderInfoTickets.getTicketPrice());
                orderChangeTickets.setCabin(orderInfoTickets.getCabin());
                orderChangeTickets.setArrivalTime(orderInfoTickets.getArrivalTime());
                orderChangeTickets.setGuestType(orderInfoTickets.getGuestType());
                orderChangeTickets.setGuestBirthday(orderInfoTickets.getGuestBirthday());
                orderChangeTickets.setGuestIdno(orderInfoTickets.getGuestIdno());
                orderChangeTickets.setOldTicketNo(orderInfoTickets.getTicketNo());
                orderChangeTickets.setPlaneStyle(orderInfoTickets.getFlightType());
                orderChangeTickets.setDepTerm(orderInfoTickets.getDepTerm());
                orderChangeTickets.setArrTerm(orderInfoTickets.getArrTerm());
                orderChangeTickets.setPnr(orderInfo.getPnr());
                orderChangeTickets.setBigPnr(orderInfo.getBigpnr());
                orderChangeTickets.setDeparture(orderInfoTickets.getDeparture());
                orderChangeTickets.setArrival(orderInfoTickets.getArrival());
                orderChangeTickets.setOrgAirport(orderInfoTickets.getOrgAirport());
                orderChangeTickets.setDstAirport(orderInfoTickets.getDstAirport());
                orderChangeTickets.setGuestMobile(orderInfoTickets.getGuestMobile());
                orderChangeTickets.setActionCode("XX");
                changeTicketsService.insertFlightOrderChangeTickets(orderChangeTickets);
            }
            response.setAmount(totalAmount.toString());
            response.setDeduction(totalDeduction.toString());
            response.setNetRefund(totalNetRefund.toString());
            response.setSuccess(true);
            response.setMsg(success);

        } catch (Exception e) {
            response.setSuccess(false);
            response.setCode(EnumHelper.ReturnCode.系统异常代码.toString());
            response.setMsg(e.getMessage());
            return response;
        }

        return response;

    }

    /**
     * 确认退票请求(CRM)
     *
     * @return
     */
    public CalculateRefundRes autoRefundTicketCRM(String orderId, List<MoPassenger> ticketNo) {
        CalculateRefundRes response = new CalculateRefundRes();
        BigDecimal totalAmount = new BigDecimal("0.0");
        BigDecimal totalDeduction = new BigDecimal("0.0");
        BigDecimal totalNetRefund = new BigDecimal("0.0");
        String totalTicketNumber = "";
        String success = "";
        try {
            FlightOrderInfo orderInfo = orderInfoService.selectFlightOrderInfo(orderId); //获取订单主表信息
            Long baseOrderId = orderInfo.getOrderId();//获取ID


            //获取订单详细信息
            List<FlightOrderInfoTickets> ticketList = orderInfoTicketsService.selectOrderInfoTicketByOrderId(baseOrderId);

            String refundNumber = "";
            if (orderInfo.getTripType().equals(FlightOrderConstants.ow.toString())) {
                for (FlightOrderInfoTickets flightOrderInfoTickets : ticketList) {
                    String strResponseData = "";
                    String reqStrData = String.format("<TES_AirTicketRefundRQ>\n" +
                            "    <POS>\n" +
                            "        <Source PseudoCityCode=\"%s\" />\n" +
                            "    </POS>\n" +
                            "    <TicketRefundInfoDetails>\n" +
                            "        <TicketRefundInfoDetail ReturnRefundFormInfoInd=\"true\" ConfirmRefundInd=\"true\">\n" +
                            "            <TicketItemInfo TicketNumber=\"%s\" />\n" +
                            "            <PrinterInfo Number=\"1\" Type=\"BSP_DOMESTIC_ETICKET\" />\n" +
                            "        </TicketRefundInfoDetail>\n" +
                            "    </TicketRefundInfoDetails>\n" +
                            "</TES_AirTicketRefundRQ>", OFFICE, flightOrderInfoTickets.getTicketNo());

                    strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketRefund", reqStrData);
                    XElement root = XElement.loadXml(strResponseData);
                    XmlMapper xmlMapper = new XmlMapper();
                    if (root.toString().contains("Errors")) {
                        response.setSuccess(false);
                        response.setMsg(root.element("Errors").element("Error").getAttributeValue("ShortText"));
                        response.setCode(root.element("Errors").element("Error").getAttributeValue("Code"));
                        return response;
                    }

                    success = xmlMapper.readValue(root.element("Success").toString(), String.class);
                    //净退额
                    String NetRefund = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("NetRefund");
                    //扣款
                    String Deduction = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("Deduction");
                    //手续费
                    String Amount = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("CommissionInfo").element("Base").getAttributeValue("Amount");
                    //票号
                    String TicketNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("TicketItemInfo").getAttributeValue("TicketNumber");
                    //退票单号
                    refundNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").getAttributeValue("Number");
                    totalAmount = totalAmount.add(new BigDecimal(Amount));
                    totalDeduction = totalDeduction.add(new BigDecimal(Deduction));
                    totalNetRefund = totalNetRefund.add(new BigDecimal(NetRefund));
                    totalTicketNumber += TicketNumber + ",";

                    ticketList.forEach(item -> {
                        item.setGuestStatus("2");
                        orderInfoTicketsService.updateFlightOrderInfoTickets(item);
                    });
                    //TODO 其他字段
                    response.getNumber().add(totalTicketNumber.substring(0, totalTicketNumber.length() - 1));
                }
            } else if (orderInfo.getTripType().equals(FlightOrderConstants.rt.toString())) {
                for (MoPassenger passenger : ticketNo) {
                    String strResponseData = "";
                    String reqStrData = String.format("<TES_AirTicketRefundRQ>\n" +
                            "    <POS>\n" +
                            "        <Source PseudoCityCode=\"%s\" />\n" +
                            "    </POS>\n" +
                            "    <TicketRefundInfoDetails>\n" +
                            "        <TicketRefundInfoDetail ReturnRefundFormInfoInd=\"true\" ConfirmRefundInd=\"true\">\n" +
                            "            <TicketItemInfo TicketNumber=\"%s\" />\n" +
                            "            <PrinterInfo Number=\"1\" Type=\"BSP_DOMESTIC_ETICKET\" />\n" +
                            "        </TicketRefundInfoDetail>\n" +
                            "    </TicketRefundInfoDetails>\n" +
                            "</TES_AirTicketRefundRQ>", OFFICE, passenger.TicketNo);

                    strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketRefund", reqStrData);
                    XElement root = XElement.loadXml(strResponseData);
                    XmlMapper xmlMapper = new XmlMapper();
                    if (root.toString().contains("Errors")) {
                        response.setSuccess(false);
                        response.setMsg(root.element("Errors").element("Error").getAttributeValue("ShortText"));
                        response.setCode(root.element("Errors").element("Error").getAttributeValue("Code"));
                        return response;
                    }

                    success = xmlMapper.readValue(root.element("Success").toString(), String.class);
                    //净退额
                    String NetRefund = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("NetRefund");
                    //扣款
                    String Deduction = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("Deduction");
                    //手续费
                    String Amount = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("CommissionInfo").element("Base").getAttributeValue("Amount");
                    //票号
                    String TicketNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("TicketItemInfo").getAttributeValue("TicketNumber");
                    //退票单号
                    refundNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").getAttributeValue("Number");
                    totalAmount = totalAmount.add(new BigDecimal(Amount));
                    totalDeduction = totalDeduction.add(new BigDecimal(Deduction));
                    totalNetRefund = totalNetRefund.add(new BigDecimal(NetRefund));
                    totalTicketNumber += TicketNumber + ",";

                    ticketList.forEach(item -> {
                        ticketNo.forEach(items -> {
                            if (item.getTicketNo().equals(items.TicketNo)) {
                                item.setGuestStatus("2");
                                orderInfoTicketsService.updateFlightOrderInfoTickets(item);
                            }
                        });
                    });
                    //TODO 其他字段
                    response.getNumber().add(totalTicketNumber.substring(0, totalTicketNumber.length() - 1));
                }
            }
            response.setRefundNumber(refundNumber);
            response.setAmount(totalAmount.toString());
            response.setDeduction(totalDeduction.toString());
            response.setNetRefund(totalNetRefund.toString());
            response.setSuccess(true);
            response.setMsg(success);

        } catch (Exception e) {
            response.setSuccess(false);
            response.setCode(EnumHelper.ReturnCode.系统异常代码.toString());
            response.setMsg(e.getMessage());
            return response;
        }

        return response;

    }

    /**
     * 改签确认退票请求
     *
     * @return
     */
    public CalculateRefundRes changeRefundTicket(String orderId, String ticketNo) {
        CalculateRefundRes response = new CalculateRefundRes();
        BigDecimal totalAmount = new BigDecimal("0.0");
        BigDecimal totalDeduction = new BigDecimal("0.0");
        BigDecimal totalNetRefund = new BigDecimal("0.0");
        String totalTicketNumber = "";
        String success = "";
        try {
            FlightOrderChange flightOrderChange = flightOrderChangeService.selectFlightOrderChangeById(orderId);
            FlightOrderInfo orderInfo = orderInfoService.selectFlightOrderInfo(String.valueOf(flightOrderChange.getOrderId())); //获取订单主表信息
            FlightOrderChangeTickets tickets = changeTicketsService.queryOrderChangeTickets(ticketNo);
            String strResponseData = "";
            String reqStrData = String.format("<TES_AirTicketRefundRQ>\n" +
                    "    <POS>\n" +
                    "        <Source PseudoCityCode=\"%s\" />\n" +
                    "    </POS>\n" +
                    "    <TicketRefundInfoDetails>\n" +
                    "        <TicketRefundInfoDetail ReturnRefundFormInfoInd=\"true\" ConfirmRefundInd=\"true\">\n" +
                    "            <TicketItemInfo TicketNumber=\"%s\" />\n" +
                    "            <PrinterInfo Number=\"1\" Type=\"BSP_DOMESTIC_ETICKET\" />\n" +
                    "        </TicketRefundInfoDetail>\n" +
                    "    </TicketRefundInfoDetails>\n" +
                    "</TES_AirTicketRefundRQ>", OFFICE, ticketNo);

            strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketRefund", reqStrData);
            XElement root = XElement.loadXml(strResponseData);
            XmlMapper xmlMapper = new XmlMapper();
            if (root.toString().contains("Errors")) {
                response.setSuccess(false);
                response.setMsg(root.element("Errors").element("Error").getAttributeValue("ShortText"));
                response.setCode(root.element("Errors").element("Error").getAttributeValue("Code"));
                return response;
            }

            success = xmlMapper.readValue(root.element("Success").toString(), String.class);
            //净退额
            String NetRefund = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("NetRefund");
            //扣款
            String Deduction = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("Deduction");
            //手续费
            String Amount = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("CommissionInfo").element("Base").getAttributeValue("Amount");
            //票号
            String TicketNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("TicketItemInfo").getAttributeValue("TicketNumber");
            //退票单号
            String refundNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").getAttributeValue("Number");
            totalAmount = totalAmount.add(new BigDecimal(Amount));
            totalDeduction = totalDeduction.add(new BigDecimal(Deduction));
            totalNetRefund = totalNetRefund.add(new BigDecimal(NetRefund));
            totalTicketNumber += TicketNumber + ",";
            //TODO 其他字段
            response.getNumber().add(totalTicketNumber.substring(0, totalTicketNumber.length() - 1));
            //退改签记录
            FlightOrderChange orderChange = new FlightOrderChange();
            SnowflakeUtils snowflakeUtils = new SnowflakeUtils();
            orderChange.setChangeOrderId(snowflakeUtils.nextId() + "-T"); //退票标识主键
            orderChange.setIsdealing("1"); //是否处理（0否，1是）
            orderChange.setCardnumber(orderInfo.getCustomerCardId());
            orderChange.setCardholder(orderInfo.getCustomerName());
            //TODO 退款原因（1自愿，非自愿2）、核销手续费
            orderChange.setOrderId(flightOrderChange.getOrderId()); //订单基本信息id
            orderChange.setChangeStatus(FlightOrderConstants.refundTicketStatus_success.getValue()); //退票状态
            orderChange.setAddTime(DateUtils.getNowDate()); //退废申请时间
            orderChange.setChangeType(FlightOrderChangeConstants.refund.getValue());
            orderChange.setOldChangeOrderId(flightOrderChange.getChangeOrderId());
            orderChange.setRefundNumber(refundNumber);
            flightOrderChangeService.insertFlightOrderChange(orderChange);
            orderInfo.setChangeOrderId(orderChange.getChangeOrderId());
            orderInfoService.updateFlightOrderInfo(orderInfo);

            FlightOrderChangeTickets orderChangeTickets = new FlightOrderChangeTickets();
            orderChangeTickets.setChangeTicketId(snowflakeUtils.nextId());
            orderChangeTickets.setOrderId(orderInfo.getOrderId());
            orderChangeTickets.setChangeOrderId(orderChange.getChangeOrderId());
            orderChangeTickets.setFlight(tickets.getFlight());
            orderChangeTickets.setAirliner(tickets.getAirliner());
            orderChangeTickets.setCustomerId(orderInfo.getCustomerId());
            orderChangeTickets.setDepartureTime(tickets.getDepartureTime());
            orderChangeTickets.setIdTypeId(tickets.getIdTypeId());
            orderChangeTickets.setGuestName(tickets.getGuestName());
            orderChangeTickets.setTicketPrice(tickets.getTicketPrice());
            orderChangeTickets.setCabin(tickets.getCabin());
            orderChangeTickets.setArrivalTime(tickets.getArrivalTime());
            orderChangeTickets.setGuestType(tickets.getGuestType());
            orderChangeTickets.setGuestBirthday(tickets.getGuestBirthday());
            orderChangeTickets.setGuestIdno(tickets.getGuestIdno());
            orderChangeTickets.setOldTicketNo(tickets.getTicketNo());
            orderChangeTickets.setPlaneStyle(tickets.getPlaneStyle());
            orderChangeTickets.setDepTerm(tickets.getDepTerm());
            orderChangeTickets.setArrTerm(tickets.getArrTerm());
            orderChangeTickets.setPnr(tickets.getPnr());
            orderChangeTickets.setBigPnr(tickets.getBigPnr());
            orderChangeTickets.setDeparture(tickets.getDeparture());
            orderChangeTickets.setArrival(tickets.getArrival());
            orderChangeTickets.setOrgAirport(tickets.getOrgAirport());
            orderChangeTickets.setDstAirport(tickets.getDstAirport());
            orderChangeTickets.setGuestMobile(tickets.getGuestMobile());
            orderChangeTickets.setActionCode("XX");
            changeTicketsService.insertFlightOrderChangeTickets(orderChangeTickets);
            response.setAmount(totalAmount.toString());
            response.setDeduction(totalDeduction.toString());
            response.setNetRefund(totalNetRefund.toString());
            response.setSuccess(true);
            response.setMsg(success);

        } catch (Exception e) {
            response.setSuccess(false);
            response.setCode(EnumHelper.ReturnCode.系统异常代码.toString());
            response.setMsg(e.getMessage());
            return response;
        }

        return response;

    }

    /**
     * CRM改签确认退票请求
     *
     * @return
     */
    public CalculateRefundRes changeRefundTicketCRM(String orderId, String ticketNo) {
        CalculateRefundRes response = new CalculateRefundRes();
        BigDecimal totalAmount = new BigDecimal("0.0");
        BigDecimal totalDeduction = new BigDecimal("0.0");
        BigDecimal totalNetRefund = new BigDecimal("0.0");
        String totalTicketNumber = "";
        String success = "";
        try {
            FlightOrderChange flightOrderChange = flightOrderChangeService.selectFlightOrderChangeById(orderId);
            FlightOrderInfo orderInfo = orderInfoService.selectFlightOrderInfo(String.valueOf(flightOrderChange.getOrderId())); //获取订单主表信息
            FlightOrderChangeTickets tickets = changeTicketsService.queryOrderChangeTickets(ticketNo);
            String strResponseData = "";
            String reqStrData = String.format("<TES_AirTicketRefundRQ>\n" +
                    "    <POS>\n" +
                    "        <Source PseudoCityCode=\"%s\" />\n" +
                    "    </POS>\n" +
                    "    <TicketRefundInfoDetails>\n" +
                    "        <TicketRefundInfoDetail ReturnRefundFormInfoInd=\"true\" ConfirmRefundInd=\"true\">\n" +
                    "            <TicketItemInfo TicketNumber=\"%s\" />\n" +
                    "            <PrinterInfo Number=\"1\" Type=\"BSP_DOMESTIC_ETICKET\" />\n" +
                    "        </TicketRefundInfoDetail>\n" +
                    "    </TicketRefundInfoDetails>\n" +
                    "</TES_AirTicketRefundRQ>", OFFICE, ticketNo);

            strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketRefund", reqStrData);
            XElement root = XElement.loadXml(strResponseData);
            XmlMapper xmlMapper = new XmlMapper();
            if (root.toString().contains("Errors")) {
                response.setSuccess(false);
                response.setMsg(root.element("Errors").element("Error").getAttributeValue("ShortText"));
                response.setCode(root.element("Errors").element("Error").getAttributeValue("Code"));
                return response;
            }

            success = xmlMapper.readValue(root.element("Success").toString(), String.class);
            //净退额
            String NetRefund = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("NetRefund");
            //扣款
            String Deduction = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").getAttributeValue("Deduction");
            //手续费
            String Amount = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("CommissionInfo").element("Base").getAttributeValue("Amount");
            //票号
            String TicketNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").element("RefundFormInfo").element("TicketItemInfo").getAttributeValue("TicketNumber");
            //退票单号
            String refundNumber = root.element("RefundFormDetails").element("RefundFormDetail").element("RefundForm").getAttributeValue("Number");
            totalAmount = totalAmount.add(new BigDecimal(Amount));
            totalDeduction = totalDeduction.add(new BigDecimal(Deduction));
            totalNetRefund = totalNetRefund.add(new BigDecimal(NetRefund));
            totalTicketNumber += TicketNumber + ",";
            //TODO 其他字段
            response.getNumber().add(totalTicketNumber.substring(0, totalTicketNumber.length() - 1));
            response.setRefundNumber(refundNumber);
            response.setAmount(totalAmount.toString());
            response.setDeduction(totalDeduction.toString());
            response.setNetRefund(totalNetRefund.toString());
            response.setSuccess(true);
            response.setMsg(success);

        } catch (Exception e) {
            response.setSuccess(false);
            response.setCode(EnumHelper.ReturnCode.系统异常代码.toString());
            response.setMsg(e.getMessage());
            return response;
        }

        return response;

    }


    /**
     * 自动计算退票费（退票前的确认信息，计算退票费用,E31接口）
     */
    public CalculateRefundRes autoCalculateRefundFee(List<String> ticketNo, boolean voluntary) {

        CalculateRefundRes response = new CalculateRefundRes();
        String strResponseData = "";
        String reqStrData = String.format("<TES_AirTicketRefundCPRQ>\n" +
                "    <POS>\n" +
                "        <Source CityCode=\"PEK\" PseudoCityCode=\"%s\">\n" +
                "            <RequestorID Type=\"1\" IDContext=\"IATA_Number\" ID=\"%s\" />\n" +
                "        </Source>\n" +
                "    </POS>\n", OFFICE, IATACODE);

        for (int i = 0; i < ticketNo.size(); i++) {
            reqStrData += String.format("<TicketRefundDetailInfo>\n" +
                    "        <PrinterInfo PrintDeviceNo=\"1\" />\n" +
                    "        <TicketRefundInfo ETicketType=\"DOMESTIC\" TicketNumber=\"%s\" />    </TicketRefundDetailInfo>\n", ticketNo.get(i));
            response.getNumber().add(ticketNo.get(i));
        }
        reqStrData += String.format("</TES_AirTicketRefundCPRQ>");
        try {

            strResponseData = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketRefundCompute", reqStrData);

            XElement root = XElement.loadXml(strResponseData);

            XmlMapper xmlMapper = new XmlMapper();
            if (root.toString().contains("Errors")) {
                response.setSuccess(false);
                response.setMsg(root.element("Errors").element("Error").getAttributeValue("ShortText"));
                response.setCode(root.element("Errors").element("Error").getAttributeValue("Code"));
                return response;
            }

            //获取退票费信息
            //代理费
            String commission = xmlMapper.readValue(root.element("RefundFormDetail").element("CommissionInfo").element("Commission").toString(), String.class);

            XElement refundInfo = root.element("RefundFormDetail").element("RefundInfo");
            //退款毛额总和
            String grossRefund = xmlMapper.readValue(refundInfo.element("GrossRefund").toString(), String.class);
            //退票手续费总和
            String deduction = xmlMapper.readValue(refundInfo.element("Deduction").toString(), String.class);
            //净退总和
            String netRefund = xmlMapper.readValue(refundInfo.element("NetRefund").toString(), String.class);
            //航空公司向旅客退还的费用
            String airlineRefund = xmlMapper.readValue(refundInfo.element("AirlineRefund").toString(), String.class);

            BigDecimal total = new BigDecimal(commission).add(new BigDecimal(netRefund));

            //判断用户退票是自愿 | 费自愿
            //FlightOrderChange flightOrderChangeInfo = flightOrderChangeService.getFlightOrderChangeInfoByOrderNo(orderNo);
            //if (flightOrderChangeInfo.getRefundReason().equals("1")) { //自愿退票
            //    total = total.subtract(new BigDecimal(20)); //用户自愿退票 减去 20元 手工费
            //}
            BigDecimal amount = new BigDecimal(0);
            if (voluntary) { //自愿退票
                total = total.subtract(new BigDecimal(20)); //用户自愿退票 减去 20元 手工费
                amount = BigDecimal.valueOf(20);
                deduction = String.valueOf(amount.add(new BigDecimal(commission)));
            }

            response.setSuccess(true);
            response.setAmount(String.valueOf(amount));
            response.setDeduction(deduction);
            response.setNetRefund(total.toString());


        } catch (Exception e) {
            response.setSuccess(false);
            response.setCode(EnumHelper.ReturnCode.系统异常代码.toString());
            response.setMsg(e.getMessage());
            return response;
        }

        return response;
    }


    /**
     * 改签机票请求数据
     *
     * @return
     */
    private XElement ticketChangesFlight(MoOrderChangeRequest moRequest) {
        String strRequest = String.format("<OTA_AirReIssueAutoTicketRQ>\n" +
                "    <POS>\n" +
                "        <Source PseudoCityCode=\"%s\" OtherID=\"1\">\n" +
                "        </Source>\n" +
                "    </POS>\n" +
                "    <DemandTicketDetail ReconfirmSegmentInd=\"true\" ReturnTicketInfoInd=\"true\" LimitSegmentStatusInd=\"true\">\n" +
                "        <AirItinerary>\n" +
                "            <OriginDestinationOptions>\n", OFFICE);
        for (int i = 0; i < moRequest.ListChangeSegementInfo.size(); i++) {
            strRequest += String.format("<OriginDestinationOption>\n" +
                            "                    <FlightSegment RPH=\"%s\" DepartureDateTime=\"%s\" ArrivalDateTime=\"%s\" CodeshareInd=\"false\" FlightNumber=\"%s\" Status=\"HK\" SegmentType=\"NORMAL\">\n" +
                            "                        <DepartureAirport LocationCode=\"%s\" />\n" +
                            "                        <ArrivalAirport LocationCode=\"%s\" />\n" +
                            "                        <Equipment AirEquipType=\"%s\" />\n" +
                            "                        <MarketingAirline Code=\"%s\" />\n" +
                            "                        <OperatingAirline Code=\"%s\" />\n" +
                            "                        <BookingClassAvail ResBookDesigCode=\"%s\" />\n" +
                            "                    </FlightSegment>\n" +
                            "                </OriginDestinationOption>\n", (i + 1), date(moRequest.ListChangeSegementInfo.get(i).TakeoffDate, "yyyy-MM-dd HH:mm:ss"), date(moRequest.ListChangeSegementInfo.get(i).ArrivalTime, "yyyy-MM-dd HH:mm:ss"), moRequest.ListChangeSegementInfo.get(i).DestinFlight,
                    moRequest.ListChangeSegementInfo.get(i).NewDPort, moRequest.ListChangeSegementInfo.get(i).NewAPort,
                    moRequest.ListChangeSegementInfo.get(i).PlaneStyle, moRequest.ListChangeSegementInfo.get(i).airline
                    , moRequest.ListChangeSegementInfo.get(i).airline, moRequest.ListChangeSegementInfo.get(i).NewClass);
        }

        strRequest += String.format("            </OriginDestinationOptions>\n" +
                "        </AirItinerary>\n" +
                "        <BookingReferenceID ID=\"%s\" ID_Context=\"PNR\">\n" +
                "        </BookingReferenceID>\n" +
                "        <PaymentInfo PaymentType=\"CASH\" CurrencyCode=\"CNY\"></PaymentInfo>\n", moRequest.pnr);  //moRequest.OrderId----->PNR


        //获取乘客信息
        FlightOrderInfoTickets info = orderInfoTicketsService.getFlightOrderInfoByTicketNo(moRequest.ticketNo);

        strRequest += String.format("<ReIssueInfos>\n" +
                        "            <ReIssueInfo>\n" +
                        "                <ReIssuePriceRQ>\n" +
                        "                    <TicketNumber_Before>%s</TicketNumber_Before>\n" +
                        "                    <IsInfant>%s</IsInfant>\n" +
                        "                    <PassName>%s</PassName>\n" +
                        "                    <InvoluntaryIdentifier>false</InvoluntaryIdentifier>\n" +
                        "                    <AirlineCode>%s</AirlineCode>\n" +
                        "                    <IataCode>%s</IataCode>\n" +
                        "                    <CityCode>BJS</CityCode>\n" +
                        "                    <Endorsement Info=\"不得退改签\" />\n" +
                        "                </ReIssuePriceRQ>\n" +
                        "                <ReIssuePriceInfo>\n" +
                        "                    <ExchangeType>1</ExchangeType>\n" +
                        "                    <ExchangeFee>0.0</ExchangeFee>\n" +
                        "                    <ChangeFee>0.0</ChangeFee>\n" +
                        "                    <TicketFare>%s</TicketFare>\n" +
                        "                    <FareDiff>%s</FareDiff>\n" +
                        "                    <TaxDiff>0.00</TaxDiff>\n" +
                        "                    <TotalFare>%s</TotalFare>\n" +
                        "                </ReIssuePriceInfo>\n" +
                        "            </ReIssueInfo>\n" +
                        "        </ReIssueInfos>\n" +
                        "    </DemandTicketDetail>\n" +
                        "</OTA_AirReIssueAutoTicketRQ>", moRequest.ticketNo, false, info.getGuestName(), moRequest.ListChangeSegementInfo.get(0).airline,
                IATACODE, moRequest.TicketFee, moRequest.PayAmount, moRequest.PayAmount);

        //判断是否no位
        XElement xElement = getOTAAirResRetByPnrId(moRequest.pnr);
        if (xElement.toString().contains("Errors")) {
            return xElement;
        }
        XElement FlightSegmentList = xElement.element("AirResRet").element("FlightSegments").element("FlightSegment");
        String goStatus = FlightSegmentList.getAttributeValue("Status");
        XElement noXElement = new XElement();
        if ("NO".equals(goStatus)) {
            List<FlightOrderInfoTickets> ticketList = new ArrayList<>();
            FlightOrderChangeTickets ticketsByPNR = changeTicketsService.queryTicketsByPNR(moRequest.pnr);
            FlightOrderInfoTickets tickets = new FlightOrderInfoTickets();
            BeanUtils.copyProperties(ticketsByPNR, tickets);
            tickets.setTripType("ow");
            ticketList.add(tickets);
            noXElement = noComplement(moRequest.pnr, ticketList);
            if (noXElement.toString().contains("Errors")) {
                return noXElement;
            }
        }

        String strResponse = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirReIssueAutoTicket", strRequest);

        XElement root = XElement.loadXml(strResponse);

        return root;

    }

    /**
     * 按行删除pnr信息
     * @param pnr
     * @return
     */
    public XElement airBookModifyRQ(String str, String pnr) {
        String strRequest = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<OTA_AirBookModifyRQ>\n" +
                "    <POS>\n" +
                "        <Source PseudoCityCode=\"%s\" />\n" +
                "    </POS>\n" +
                "    <AirBookModifyRQ ModificationType=\"ITEM_CANCEL\">\n" +
                "        <AirReservation>\n" +
                "            <BookingReferenceID ID_Context=\"%s\" />\n" +
                "        </AirReservation>\n" +
                "    </AirBookModifyRQ>\n" +
                "    <AirReservation>\n" +
                "        <BookingReferenceID ID=\"%S\" />\n" +
                "    </AirReservation>\n" +
                "</OTA_AirBookModifyRQ>", OFFICE, str, pnr);
        String strResponse = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirBookModify", strRequest);
        XElement root = XElement.loadXml(strResponse);
        return root;
    }

    /**
     * QT-查询office下所有信箱类型
     * @return
     */
    public XElement QMsg() {
        String strRequest = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<OTA_QMsgRQ>\n" +
                "    <ActionCode>OPQT</ActionCode>\n" +
                "    <DisType>C</DisType>\n" +
                "    <Queue Office=\"%s\" />\n" +
                "</OTA_QMsgRQ>", OFFICE);
        String strResponse = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/QMsg", strRequest);
        XElement element = XElement.loadXml(strResponse);
        return element;
    }

    /**
     * QR-查询信箱详情
     * @param queueType
     * @return
     */
    public XElement QMsgSC(String queueType) {
        String strRequest = String.format("<OTA_QMsgRQ>\n" +
                "    <ActionCode>OPQR</ActionCode>\n" +
                "    <MaxRow>20</MaxRow>\n" +
                "    <Queue QueueType=\"%s\" Office=\"%s\" />\n" +
                "</OTA_QMsgRQ>", queueType, OFFICE);
        String strResponse = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/QMsg", strRequest);
        XElement element = XElement.loadXml(strResponse);
        return element;
    }

    /**
     * 根据票号提取电子客票
     * @param ticketNo
     * @return
     */
    public XElement airTicket(String ticketNo) {
        String strRequest = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<TES_AirTicketRetRQ>\n" +
                "    <POS>\n" +
                "        <Source PseudoCityCode=\"%s\" />\n" +
                "    </POS>\n" +
                "    <TicketNumber>%s</TicketNumber>\n" +
                "</TES_AirTicketRetRQ>", OFFICE, ticketNo);
        String airTicketRet = HttpHelper.sendByHttps(USER_NAME, USER_PWD, URL + "/AirTicketRet", strRequest);
        XElement element = XElement.loadXml(airTicketRet);
        return element;
    }


    /**
     * 18位身份证获取性别和年龄
     *
     * @param CardCode
     * @return
     * @throws Exception
     */
    private Map<String, Object> identityCard18(String CardCode) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        Map<String, Object> map = new HashMap<String, Object>();
        // 得到年份
        String year = CardCode.substring(6).substring(0, 4);
        // 得到月份
        String month = CardCode.substring(10).substring(0, 2);
        //得到日
        //String day=CardCode.substring(12).substring(0,2);
        String sex;
        // 判断性别
        if (Integer.parseInt(CardCode.substring(16).substring(0, 1)) % 2 == 0) {
            sex = "女";
        } else {
            sex = "男";
        }
        // 得到当前的系统时间
        Date date = new Date();
        // 当前年份
        String currentYear = format.format(date).substring(0, 4);
        // 月份
        String currentMonth = format.format(date).substring(5, 7);
        //String currentdDay=format.format(date).substring(8,10);
        int age = 0;
        // 当前月份大于用户出身的月份表示已过生日
        if (Integer.parseInt(month) <= Integer.parseInt(currentMonth)) {
            age = Integer.parseInt(currentYear) - Integer.parseInt(year) + 1;
        } else {
            // 当前用户还没过生日
            age = Integer.parseInt(currentYear) - Integer.parseInt(year);
        }
        map.put("sex", sex);
        map.put("age", age);
        return map;
    }

    /**
     * 15位身份证获取性别和年龄
     *
     * @param card
     * @return
     * @throws Exception
     */
    private Map<String, Object> identityCard15(String card) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        Map<String, Object> map = new HashMap<String, Object>();
        //年份
        String year = "19" + card.substring(6, 8);
        //月份
        String yue = card.substring(8, 10);
        //日
        //String day=card.substring(10, 12);
        String sex;
        if (Integer.parseInt(card.substring(14, 15)) % 2 == 0) {
            sex = "女";
        } else {
            sex = "男";
        }
        // 得到当前的系统时间
        Date date = new Date();
        //当前年份
        String currentYear = format.format(date).substring(0, 4);
        //月份
        String currentMonth = format.format(date).substring(5, 7);
        //String fday=format.format(date).substring(8,10);
        int age = 0;
        //当前月份大于用户出身的月份表示已过生日
        if (Integer.parseInt(yue) <= Integer.parseInt(currentMonth)) {
            age = Integer.parseInt(currentYear) - Integer.parseInt(year) + 1;
        } else {
            // 当前用户还没过生日
            age = Integer.parseInt(currentYear) - Integer.parseInt(year);
        }
        map.put("sex", sex);
        map.put("age", age);
        return map;
    }

    /**
     * 拆解税费字符串
     * @param taxInfo
     * @return
     */
    public String[] getTaxInfo(String taxInfo)
    {
        String[] cnTax = new String[2];
        if (taxInfo.indexOf(",")!=-1)
        {
            String cnTaxInfo = taxInfo;
            String tmpCnTaxInfo = taxInfo.substring(1, cnTaxInfo.length() - 1);
            cnTax = tmpCnTaxInfo.split(",");
        }else
        {
            cnTax[0] = taxInfo;
        }
        return cnTax;
    }

    private String meal(String meal) {
        String Meal = "";
        if (meal.equals("B")) {
            Meal = "早餐";
        } else if (meal.equals("C")) {
            Meal = "免费酒精饮料";
        } else if (meal.equals("D")) {
            Meal = "正餐";
        } else if (meal.equals("F")) {
            Meal = "供采购的食物";
        } else if (meal.equals("G")) {
            Meal = "供采购的食物和饮料";
        } else if (meal.equals("H")) {
            Meal = "热的膳食";
        } else if (meal.equals("K")) {
            Meal = "轻快早餐";
        } else if (meal.equals("L")) {
            Meal = "午餐";
        } else if (meal.equals("M")) {
            Meal = "膳食";
        } else if (meal.equals("N")) {
            Meal = "没有饭食供应";
        } else if (meal.equals("O")) {
            Meal = "冷的膳食";
        } else if (meal.equals("P")) {
            Meal = "供采购的酒精饮料";
        } else if (meal.equals("R")) {
            Meal = "茶点";
        } else if (meal.equals("S")) {
            Meal = "快餐";
        } else if (meal.equals("V")) {
            Meal = "供采购的茶点";
        }
        return Meal;
    }

    private String dateProcessing(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.format(date);
    }
}

